﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.Screens.MissionScreen
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using TaleWorlds.Core;
using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.Engine.Options;
using TaleWorlds.Engine.Screens;
using TaleWorlds.InputSystem;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.MountAndBlade.View.MissionViews;
using TaleWorlds.MountAndBlade.View.MissionViews.Order;
using TaleWorlds.MountAndBlade.ViewModelCollection;
using TaleWorlds.ScreenSystem;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.Screens
{
  [GameStateScreen(typeof (MissionState))]
  public class MissionScreen : 
    ScreenBase,
    IMissionSystemHandler,
    IGameStateListener,
    IMissionScreen,
    IMissionListener
  {
    public const int LoadingScreenFramesLeftInitial = 15;
    public Func<BasicCharacterObject> GetSpectatedCharacter;
    private MissionScreen.GatherCustomAgentListToSpectateDelegate _gatherCustomAgentListToSpectate;
    public const float MinCameraAddedDistance = 0.7f;
    public const float MinCameraDistanceHardLimit = 0.48f;
    public const float MaxCameraAddedDistance = 2.4f;
    private const int _cheatTimeSpeedRequestId = 1121;
    private const string AttackerCameraEntityTag = "strategyCameraAttacker";
    private const string DefenderCameraEntityTag = "strategyCameraDefender";
    private const string CameraHeightLimiterTag = "camera_height_limiter";
    private float _cameraRayCastOffset;
    private bool _forceCanZoom;
    private ScreenLayer _emptyUILayer;
    public const float DefaultViewAngle = 65f;
    private Camera _customCamera;
    private Vec3[] _cameraNearPlanePoints = new Vec3[4];
    private Vec3[] _cameraBoxPoints = new Vec3[8];
    private Vec3 _cameraTarget;
    private float _cameraBearingDelta;
    private float _cameraElevationDelta;
    private float _cameraSpecialTargetAddedBearing;
    private float _cameraSpecialCurrentAddedBearing;
    private float _cameraSpecialTargetAddedElevation;
    private float _cameraSpecialCurrentAddedElevation;
    private Vec3 _cameraSpecialTargetPositionToAdd;
    private Vec3 _cameraSpecialCurrentPositionToAdd;
    private float _cameraSpecialTargetDistanceToAdd;
    private float _cameraSpecialCurrentDistanceToAdd;
    private bool _cameraAddSpecialMovement;
    private bool _cameraAddSpecialPositionalMovement;
    private bool _cameraApplySpecialMovementsInstantly;
    private float _cameraSpecialCurrentFOV;
    private float _cameraSpecialTargetFOV;
    private float _cameraTargetAddedHeight;
    private float _cameraDeploymentHeightToAdd;
    private float _lastCameraAddedDistance;
    private float _cameraAddedElevation;
    private float _cameraHeightLimit;
    private float _currentViewBlockingBodyCoeff;
    private float _targetViewBlockingBodyCoeff;
    private bool _applySmoothTransitionToVirtualEyeCamera;
    private Vec3 _cameraSpeed;
    private float _cameraSpeedMultiplier;
    private bool _cameraSmoothMode;
    private bool _fixCamera;
    private int _shiftSpeedMultiplier = 3;
    private bool _tickEditor;
    private bool _playerDeploymentCancelled;
    private const float LookUpLimit = 1.12199748f;
    private const float LookDownLimit = -1.36590993f;
    public const float FirstPersonNearClippingDistance = 0.065f;
    public const float ThirdPersonNearClippingDistance = 0.1f;
    public const float FarClippingDistance = 12500f;
    private const float HoldTimeForCameraToggle = 0.5f;
    private bool _zoomToggled;
    private float _zoomToggleTime = float.MaxValue;
    private float _zoomAmount;
    private float _cameraToggleStartTime = float.MaxValue;
    private bool _displayingDialog;
    private MissionMainAgentController _missionMainAgentController;
    private ICameraModeLogic _missionCameraModeLogic;
    private MissionLobbyComponent _missionLobbyComponent;
    private bool _isPlayerAgentAdded = true;
    private bool _isRenderingStarted;
    private bool _onSceneRenderingStartedCalled;
    private int _loadingScreenFramesLeft = 15;
    private bool _resetDraggingMode;
    private bool _rightButtonDraggingMode;
    private Vec2 _clickedPositionPixel = Vec2.Zero;
    private Agent _agentToFollowOverride;
    private Agent _lastFollowedAgent;
    private MissionMultiplayerGameModeBaseClient _mpGameModeBase;
    private bool _isGamepadActive;
    private List<MissionView> _missionViews;
    private MissionState _missionState;
    private bool _isDeactivated;

    public bool LockCameraMovement { get; private set; }

    public event MissionScreen.OnSpectateAgentDelegate OnSpectateAgentFocusIn;

    public event MissionScreen.OnSpectateAgentDelegate OnSpectateAgentFocusOut;

    public OrderFlag OrderFlag { get; set; }

    public Camera CombatCamera { get; private set; }

    public Camera CustomCamera
    {
      get => this._customCamera;
      set => this._customCamera = value;
    }

    public float CameraBearing { get; private set; }

    public float MaxCameraZoom { get; private set; } = 1f;

    public float CameraElevation { get; private set; }

    public float CameraResultDistanceToTarget { get; private set; }

    public float CameraViewAngle { get; private set; }

    public bool IsPhotoModeEnabled { get; private set; }

    public bool IsConversationActive { get; private set; }

    public bool IsDeploymentActive => this.Mission.Mode == MissionMode.Deployment;

    public SceneLayer SceneLayer { get; private set; }

    public SceneView SceneView => this.SceneLayer?.SceneView;

    public Mission Mission { get; private set; }

    public bool IsCheatGhostMode { get; set; }

    public bool IsRadialMenuActive { get; private set; }

    public IInputContext InputManager => this.Mission.InputManager;

    private bool IsOrderMenuOpen => this.Mission.IsOrderMenuOpen;

    private bool IsTransferMenuOpen => this.Mission.IsTransferMenuOpen;

    public Agent LastFollowedAgent
    {
      get => this._lastFollowedAgent;
      private set
      {
        if (this._lastFollowedAgent == value)
          return;
        Agent lastFollowedAgent = this._lastFollowedAgent;
        this._lastFollowedAgent = value;
        NetworkCommunicator myPeer = GameNetwork.MyPeer;
        MissionPeer component = myPeer != null ? myPeer.GetComponent<MissionPeer>() : (MissionPeer) null;
        if (GameNetwork.IsMyPeerReady)
        {
          if (component != null)
            component.FollowedAgent = this._lastFollowedAgent;
          else
            Debug.FailedAssert("MyPeer.IsSynchronized but myMissionPeer == null", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\Screens\\MissionScreen.cs", nameof (LastFollowedAgent), 218);
        }
        if (lastFollowedAgent != null)
        {
          MissionScreen.OnSpectateAgentDelegate spectateAgentFocusOut = this.OnSpectateAgentFocusOut;
          if (spectateAgentFocusOut != null)
            spectateAgentFocusOut(lastFollowedAgent);
        }
        if (this._lastFollowedAgent != null)
        {
          if (this._lastFollowedAgent == this.Mission.MainAgent)
          {
            this.Mission.MainAgent.OnMainAgentWieldedItemChange += new Agent.OnMainAgentWieldedItemChangeDelegate(this.OnMainAgentWeaponChanged);
            this.ResetMaxCameraZoom();
          }
          MissionScreen.OnSpectateAgentDelegate spectateAgentFocusIn = this.OnSpectateAgentFocusIn;
          if (spectateAgentFocusIn != null)
            spectateAgentFocusIn(this._lastFollowedAgent);
        }
        if (this._lastFollowedAgent != this._agentToFollowOverride)
          return;
        this._agentToFollowOverride = (Agent) null;
      }
    }

    public IAgentVisual LastFollowedAgentVisuals { get; set; }

    float IMissionScreen.GetCameraElevation() => this.CameraElevation;

    public void SetOrderFlagVisibility(bool value)
    {
      if (this.OrderFlag == null)
        return;
      this.OrderFlag.IsVisible = value;
    }

    public string GetFollowText()
    {
      return this.LastFollowedAgent == null ? "" : this.LastFollowedAgent.Name.ToString();
    }

    public string GetFollowPartyText()
    {
      if (this.LastFollowedAgent == null)
        return "";
      TextObject textObject = new TextObject("{=xsC8Ierj}({BATTLE_COMBATANT})");
      textObject.SetTextVariable("BATTLE_COMBATANT", this.LastFollowedAgent.Origin.BattleCombatant.Name);
      return textObject.ToString();
    }

    public bool SetDisplayDialog(bool value)
    {
      int num = this._displayingDialog != value ? 1 : 0;
      this._displayingDialog = value;
      return num != 0;
    }

    bool IMissionScreen.GetDisplayDialog() => this._displayingDialog;

    public override bool MouseVisible => ScreenManager.GetMouseVisibility();

    public bool IsMissionTickable
    {
      get
      {
        if (!this.IsActive || this.Mission == null)
          return false;
        return this.Mission.CurrentState == Mission.State.Continuing || this.Mission.MissionEnded;
      }
    }

    public bool PhotoModeRequiresMouse { get; private set; }

    public MissionScreen(MissionState missionState)
    {
      missionState.Handler = (IMissionSystemHandler) this;
      this._emptyUILayer = (ScreenLayer) new SceneLayer();
      ((SceneLayer) this._emptyUILayer).SceneView.SetEnable(false);
      this._missionState = missionState;
      this.Mission = missionState.CurrentMission;
      this.CombatCamera = Camera.CreateCamera();
      this._missionViews = new List<MissionView>();
    }

    protected override void OnInitialize()
    {
      MBDebug.Print("-------MissionScreen-OnInitialize");
      base.OnInitialize();
      Module.CurrentModule.SkinsXMLHasChanged += new Action(this.OnSkinsXMLChanged);
      this.CameraViewAngle = 65f;
      this._cameraTarget = new Vec3(z: 10f);
      this.CameraBearing = 0.0f;
      this.CameraElevation = -0.2f;
      this._cameraBearingDelta = 0.0f;
      this._cameraElevationDelta = 0.0f;
      this._cameraSpecialTargetAddedBearing = 0.0f;
      this._cameraSpecialCurrentAddedBearing = 0.0f;
      this._cameraSpecialTargetAddedElevation = 0.0f;
      this._cameraSpecialCurrentAddedElevation = 0.0f;
      this._cameraSpecialTargetPositionToAdd = Vec3.Zero;
      this._cameraSpecialCurrentPositionToAdd = Vec3.Zero;
      this._cameraSpecialTargetDistanceToAdd = 0.0f;
      this._cameraSpecialCurrentDistanceToAdd = 0.0f;
      this._cameraSpecialCurrentFOV = 65f;
      this._cameraSpecialTargetFOV = 65f;
      this._cameraAddedElevation = 0.0f;
      this._cameraTargetAddedHeight = 0.0f;
      this._cameraDeploymentHeightToAdd = 0.0f;
      this._lastCameraAddedDistance = 0.0f;
      this.CameraResultDistanceToTarget = 0.0f;
      this._cameraSpeed = Vec3.Zero;
      this._cameraSpeedMultiplier = 1f;
      this._cameraHeightLimit = 0.0f;
      this._cameraAddSpecialMovement = false;
      this._cameraAddSpecialPositionalMovement = false;
      this._cameraApplySpecialMovementsInstantly = false;
      this._currentViewBlockingBodyCoeff = 1f;
      this._targetViewBlockingBodyCoeff = 1f;
      this._cameraSmoothMode = false;
      this.CustomCamera = (Camera) null;
    }

    private void InitializeMissionView()
    {
      this._missionState.Paused = false;
      this.SceneLayer = new SceneLayer();
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("Generic"));
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("GenericPanelGameKeyCategory"));
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("GenericCampaignPanelsGameKeyCategory"));
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("ScoreboardHotKeyCategory"));
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("CombatHotKeyCategory"));
      this.SceneLayer.Input.RegisterHotKeyCategory(HotKeyManager.GetCategory("Cheats"));
      this.Mission.InputManager = (IInputContext) this.SceneLayer.Input;
      this.AddLayer((ScreenLayer) this.SceneLayer);
      this.SceneView.SetScene(this.Mission.Scene);
      this.SceneView.SetSceneUsesShadows(true);
      this.SceneView.SetAcceptGlobalDebugRenderObjects(true);
      this.SceneView.SetResolutionScaling(true);
      this._missionMainAgentController = this.Mission.GetMissionBehavior<MissionMainAgentController>();
      this._missionLobbyComponent = Mission.Current.GetMissionBehavior<MissionLobbyComponent>();
      this._missionCameraModeLogic = this.Mission.MissionBehaviors.FirstOrDefault<MissionBehavior>((Func<MissionBehavior, bool>) (b => b is ICameraModeLogic)) as ICameraModeLogic;
      foreach (MissionBehavior missionBehavior in this.Mission.MissionBehaviors)
      {
        if (missionBehavior is MissionView missionView)
          missionView.OnMissionScreenInitialize();
      }
      this.Mission.AgentVisualCreator = (IAgentVisualCreator) new AgentVisualsCreator();
      this._mpGameModeBase = this.Mission.GetMissionBehavior<MissionMultiplayerGameModeBaseClient>();
    }

    protected override void OnActivate()
    {
      base.OnActivate();
      this.ActivateLoadingScreen();
      if (this.Mission == null || !this.Mission.MissionEnded || !(ScreenManager.TopScreen is MissionScreen topScreen))
        return;
      ScreenManager.TopScreen.DeactivateAllLayers();
      topScreen.SceneView.SetEnable(false);
    }

    protected override void OnResume()
    {
      base.OnResume();
      if (this.Mission == null || !this.Mission.MissionEnded || !(ScreenManager.TopScreen is MissionScreen topScreen))
        return;
      ScreenManager.TopScreen.DeactivateAllLayers();
      topScreen.SceneView.SetEnable(false);
    }

    public override void OnFocusChangeOnGameWindow(bool focusGained)
    {
      base.OnFocusChangeOnGameWindow(focusGained);
      if (!LoadingWindow.IsLoadingWindowActive)
      {
        Func<bool> anyInquiryActive = InformationManager.IsAnyInquiryActive;
        if ((anyInquiryActive != null ? (!anyInquiryActive() ? 1 : 0) : 0) != 0)
        {
          Mission mission = this.Mission;
          List<MissionBehavior> missionBehaviorList1;
          if (mission == null)
          {
            missionBehaviorList1 = (List<MissionBehavior>) null;
          }
          else
          {
            List<MissionBehavior> missionBehaviors = mission.MissionBehaviors;
            missionBehaviorList1 = missionBehaviors != null ? missionBehaviors.Where<MissionBehavior>((Func<MissionBehavior, bool>) (v => v is MissionView)).OrderBy<MissionBehavior, int>((Func<MissionBehavior, int>) (v => ((MissionView) v).ViewOrderPriority)).ToList<MissionBehavior>() : (List<MissionBehavior>) null;
          }
          List<MissionBehavior> missionBehaviorList2 = missionBehaviorList1;
          if (missionBehaviorList2 != null)
          {
            for (int index = 0; index < missionBehaviorList2.Count; ++index)
              (missionBehaviorList2[index] as MissionView).OnFocusChangeOnGameWindow(focusGained);
          }
        }
      }
      this.IsFocusLost = !focusGained;
    }

    public bool IsFocusLost { get; private set; }

    public bool IsOpeningEscapeMenuOnFocusChangeAllowed()
    {
      Mission mission = this.Mission;
      List<MissionBehavior> missionBehaviorList1;
      if (mission == null)
      {
        missionBehaviorList1 = (List<MissionBehavior>) null;
      }
      else
      {
        List<MissionBehavior> missionBehaviors = mission.MissionBehaviors;
        missionBehaviorList1 = missionBehaviors != null ? missionBehaviors.Where<MissionBehavior>((Func<MissionBehavior, bool>) (v => v is MissionView)).OrderBy<MissionBehavior, int>((Func<MissionBehavior, int>) (v => ((MissionView) v).ViewOrderPriority)).ToList<MissionBehavior>() : (List<MissionBehavior>) null;
      }
      List<MissionBehavior> missionBehaviorList2 = missionBehaviorList1;
      if (missionBehaviorList2 != null)
      {
        foreach (MissionBehavior missionBehavior in missionBehaviorList2)
        {
          if (!(missionBehavior as MissionView).IsOpeningEscapeMenuOnFocusChangeAllowed())
            return false;
        }
      }
      return true;
    }

    public void SetExtraCameraParameters(
      bool newForceCanZoom,
      float newCameraRayCastStartingPointOffset)
    {
      this._forceCanZoom = newForceCanZoom;
      this._cameraRayCastOffset = newCameraRayCastStartingPointOffset;
    }

    public void SetCustomAgentListToSpectateGatherer(
      MissionScreen.GatherCustomAgentListToSpectateDelegate gatherer)
    {
      this._gatherCustomAgentListToSpectate = gatherer;
    }

    public void UpdateFreeCamera(MatrixFrame frame)
    {
      this.CombatCamera.Frame = frame;
      Vec3 v2 = -frame.rotation.u;
      this.CameraBearing = v2.RotationZ;
      this.CameraElevation = MathF.Acos(Vec3.DotProduct(new Vec3(z: 1f), v2)) - 1.57079637f;
    }

    protected override void OnFrameTick(float dt)
    {
      if (this.SceneLayer != null)
      {
        bool flag = MBDebug.IsErrorReportModeActive();
        if (flag)
          this._missionState.Paused = MBDebug.IsErrorReportModePauseMission();
        if (this.DebugInput.IsHotKeyPressed("MissionScreenHotkeyFixCamera"))
          this._fixCamera = !this._fixCamera;
        bool isVisible = flag || this._fixCamera;
        if (this.IsPhotoModeEnabled)
          isVisible = isVisible || this.PhotoModeRequiresMouse;
        this.SceneLayer.InputRestrictions.SetMouseVisibility(isVisible);
      }
      if (this.Mission == null)
        return;
      if (this.IsMissionTickable)
      {
        foreach (MissionView missionView in this._missionViews)
          missionView.OnMissionScreenTick(dt);
      }
      this.HandleInputs();
    }

    private void ActivateMissionView()
    {
      MBDebug.Print("-------MissionScreen-OnActivate");
      this.Mission.OnMainAgentChanged += new PropertyChangedEventHandler(this.Mission_OnMainAgentChanged);
      this.Mission.OnBeforeAgentRemoved += new Mission.OnBeforeAgentRemovedDelegate(this.Mission_OnBeforeAgentRemoved);
      this._cameraBearingDelta = 0.0f;
      this._cameraElevationDelta = 0.0f;
      this.SetCameraFrameToMapView();
      this.CheckForUpdateCamera(1E-05f);
      this.Mission.ResetFirstThirdPersonView();
      if (MBEditor.EditModeEnabled && MBEditor.IsEditModeOn)
        MBEditor.EnterEditMissionMode(this.Mission);
      foreach (MissionView missionView in this._missionViews)
        missionView.OnMissionScreenActivate();
    }

    private void Mission_OnMainAgentChanged(object sender, PropertyChangedEventArgs e)
    {
      if (this.Mission.MainAgent == null)
        return;
      this._isPlayerAgentAdded = true;
    }

    private void Mission_OnBeforeAgentRemoved(
      Agent affectedAgent,
      Agent affectorAgent,
      AgentState agentState,
      KillingBlow killingBlow)
    {
      if (affectedAgent == this._agentToFollowOverride)
      {
        this._agentToFollowOverride = (Agent) null;
      }
      else
      {
        if (affectedAgent != this.Mission.MainAgent)
          return;
        this._agentToFollowOverride = affectorAgent;
      }
    }

    public void OnMainAgentWeaponChanged() => this.ResetMaxCameraZoom();

    private void ResetMaxCameraZoom()
    {
      if (this.LastFollowedAgent == null || this.LastFollowedAgent != this.Mission.MainAgent)
        this.MaxCameraZoom = 1f;
      else
        this.MaxCameraZoom = Mission.Current != null ? MathF.Max(1f, Mission.Current.GetMainAgentMaxCameraZoom()) : 1f;
    }

    protected override void OnDeactivate()
    {
      base.OnDeactivate();
      MBDebug.Print("-------MissionScreen-OnDeactivate");
      if (this.Mission == null)
        return;
      this.Mission.OnMainAgentChanged -= new PropertyChangedEventHandler(this.Mission_OnMainAgentChanged);
      this.Mission.OnBeforeAgentRemoved -= new Mission.OnBeforeAgentRemovedDelegate(this.Mission_OnBeforeAgentRemoved);
      foreach (MissionView missionView in this._missionViews)
        missionView.OnMissionScreenDeactivate();
      this._isRenderingStarted = false;
      this._loadingScreenFramesLeft = 15;
    }

    protected override void OnFinalize()
    {
      MBDebug.Print("-------MissionScreen-OnFinalize");
      Module.CurrentModule.SkinsXMLHasChanged -= new Action(this.OnSkinsXMLChanged);
      LoadingWindow.EnableGlobalLoadingWindow();
      if (this.Mission != null)
        this.Mission.InputManager = (IInputContext) null;
      this.Mission = (Mission) null;
      this.OrderFlag = (OrderFlag) null;
      this.SceneLayer = (SceneLayer) null;
      this._missionMainAgentController = (MissionMainAgentController) null;
      this.CombatCamera = (Camera) null;
      this._customCamera = (Camera) null;
      this._missionState = (MissionState) null;
      base.OnFinalize();
    }

    private IEnumerable<MissionBehavior> AddDefaultMissionBehaviorsTo(
      Mission mission,
      IEnumerable<MissionBehavior> behaviors)
    {
      List<MissionBehavior> second = new List<MissionBehavior>();
      IEnumerable<MissionBehavior> missionBehaviors = ViewCreatorManager.CreateDefaultMissionBehaviors(mission);
      second.AddRange(missionBehaviors);
      return behaviors.Concat<MissionBehavior>((IEnumerable<MissionBehavior>) second);
    }

    private void OnSkinsXMLChanged()
    {
      foreach (Agent agent in (List<Agent>) Mission.Current.Agents)
      {
        agent.EquipItemsFromSpawnEquipment(true);
        agent.UpdateAgentProperties();
        agent.AgentVisuals.UpdateSkeletonScale((int) agent.SpawnEquipment.BodyDeformType);
      }
    }

    private void OnSceneRenderingStarted()
    {
      LoadingWindow.DisableGlobalLoadingWindow();
      Utilities.SetScreenTextRenderingState(true);
      foreach (MissionView missionView in this._missionViews)
        missionView.OnSceneRenderingStarted();
    }

    [CommandLineFunctionality.CommandLineArgumentFunction("fix_camera_toggle", "mission")]
    public static string ToggleFixedMissionCamera(List<string> strings)
    {
      if (ScreenManager.TopScreen is MissionScreen topScreen)
        MissionScreen.SetFixedMissionCameraActive(!topScreen._fixCamera);
      return "Done";
    }

    public static void SetFixedMissionCameraActive(bool active)
    {
      if (!(ScreenManager.TopScreen is MissionScreen topScreen))
        return;
      topScreen._fixCamera = active;
      topScreen.SceneLayer.InputRestrictions.SetMouseVisibility(topScreen._fixCamera);
    }

    [CommandLineFunctionality.CommandLineArgumentFunction("set_shift_camera_speed", "mission")]
    public static string SetShiftCameraSpeed(List<string> strings)
    {
      if (!(ScreenManager.TopScreen is MissionScreen topScreen))
        return "No Mission Available";
      int result;
      if (strings.Count <= 0 || !int.TryParse(strings[0], out result))
        return "Current multiplier is " + topScreen._shiftSpeedMultiplier.ToString();
      topScreen._shiftSpeedMultiplier = result;
      return "Done";
    }

    [CommandLineFunctionality.CommandLineArgumentFunction("set_camera_position", "mission")]
    public static string SetCameraPosition(List<string> strings)
    {
      if (GameNetwork.IsSessionActive)
        return "Does not work on multiplayer.";
      if (strings.Count < 3)
        return "You need to enter 3 arguments.";
      List<float> floatList = new List<float>();
      for (int index = 0; index < strings.Count; ++index)
      {
        float result = 0.0f;
        if (!float.TryParse(strings[index], out result))
          return "Argument " + (object) (index + 1) + " is not valid.";
        floatList.Add(result);
      }
      if (!(ScreenManager.TopScreen is MissionScreen topScreen))
        return "Mission screen not found.";
      topScreen.IsCheatGhostMode = true;
      topScreen.LastFollowedAgent = (Agent) null;
      topScreen.CombatCamera.Position = new Vec3(floatList[0], floatList[1], floatList[2]);
      return "Camera position has been set to: " + strings[0] + ", " + strings[1] + ", " + strings[2];
    }

    private void CheckForUpdateCamera(float dt)
    {
      if (this._fixCamera && !this.IsPhotoModeEnabled)
        return;
      if ((NativeObject) this.CustomCamera != (NativeObject) null)
      {
        if ((double) this._zoomAmount > 0.0)
        {
          this._zoomAmount = MBMath.ClampFloat(this._zoomAmount, 0.0f, 1f);
          float valueTo = 37f / this.MaxCameraZoom;
          this.CameraViewAngle = MBMath.Lerp(Mission.GetFirstPersonFov(), valueTo, this._zoomAmount, 0.005f);
          this.CustomCamera.SetFovVertical((float) ((double) this._cameraSpecialCurrentFOV * ((double) this.CameraViewAngle / 65.0) * (Math.PI / 180.0)), Screen.AspectRatio, 0.065f, 12500f);
        }
        this.CombatCamera.FillParametersFrom(this.CustomCamera);
        if ((NativeObject) this.CustomCamera.Entity != (NativeObject) null)
        {
          MatrixFrame globalFrame = this.CustomCamera.Entity.GetGlobalFrame();
          globalFrame.rotation.MakeUnit();
          this.CombatCamera.Frame = globalFrame;
        }
        this.SceneView.SetCamera(this.CombatCamera);
        SoundManager.SetListenerFrame(this.CombatCamera.Frame);
      }
      else
      {
        bool flag = false;
        foreach (MissionBehavior missionBehavior in this.Mission.MissionBehaviors)
        {
          if (missionBehavior is MissionView missionView)
            flag = flag || missionView.UpdateOverridenCamera(dt);
        }
        if (flag)
          return;
        this.UpdateCamera(dt);
      }
    }

    private void UpdateDragData()
    {
      if (this._resetDraggingMode)
      {
        this._rightButtonDraggingMode = false;
        this._resetDraggingMode = false;
      }
      else if (this.SceneLayer.Input.IsKeyReleased(InputKey.RightMouseButton))
        this._resetDraggingMode = true;
      else if (this.SceneLayer.Input.IsKeyPressed(InputKey.RightMouseButton))
      {
        this._clickedPositionPixel = this.SceneLayer.Input.GetMousePositionPixel();
      }
      else
      {
        if (!this.SceneLayer.Input.IsKeyDown(InputKey.RightMouseButton) || this.SceneLayer.Input.IsKeyReleased(InputKey.RightMouseButton) || (double) this.SceneLayer.Input.GetMousePositionPixel().DistanceSquared(this._clickedPositionPixel) <= 10.0 || this._rightButtonDraggingMode)
          return;
        this._rightButtonDraggingMode = true;
      }
    }

    private void UpdateCamera(float dt)
    {
      Scene scene1 = this.Mission.Scene;
      bool photoModeOrbit = scene1.GetPhotoModeOrbit();
      float num1 = this.IsPhotoModeEnabled ? scene1.GetPhotoModeFov() : 0.0f;
      bool flag1 = this._isGamepadActive && this.PhotoModeRequiresMouse;
      this.UpdateDragData();
      MatrixFrame cameraFrame1 = MatrixFrame.Identity;
      MissionPeer component = GameNetwork.MyPeer != null ? GameNetwork.MyPeer.GetComponent<MissionPeer>() : (MissionPeer) null;
      Mission.SpectatorData spectatingData = this.GetSpectatingData(this.CombatCamera.Frame.origin);
      Agent agentToFollow = spectatingData.AgentToFollow;
      IAgentVisual agentVisualToFollow = spectatingData.AgentVisualToFollow;
      SpectatorCameraTypes cameraType = spectatingData.CameraType;
      bool flag2 = this.Mission.CameraIsFirstPerson && agentToFollow != null && agentToFollow == this.Mission.MainAgent;
      float valueFrom = flag2 ? Mission.GetFirstPersonFov() : 65f;
      if (this.IsPhotoModeEnabled)
      {
        this.CameraViewAngle = valueFrom;
      }
      else
      {
        this._zoomAmount = MBMath.ClampFloat(this._zoomAmount, 0.0f, 1f);
        float valueTo = 37f / this.MaxCameraZoom;
        this.CameraViewAngle = MBMath.Lerp(valueFrom, valueTo, this._zoomAmount, 0.005f);
      }
      if (this._missionMainAgentController == null)
        this._missionMainAgentController = this.Mission.GetMissionBehavior<MissionMainAgentController>();
      else
        this._missionMainAgentController.IsDisabled = true;
      if (this._missionMainAgentController != null && this.Mission.Mode != MissionMode.Deployment && this.Mission.MainAgent != null && this.Mission.MainAgent.IsCameraAttachable())
        this._missionMainAgentController.IsDisabled = false;
      bool flag3 = this._cameraApplySpecialMovementsInstantly;
      Vec3 closestPoint1;
      GameEntity collidedEntity;
      if (this.IsPhotoModeEnabled && !photoModeOrbit || agentToFollow == null && agentVisualToFollow == null)
      {
        float a = -scene1.GetPhotoModeRoll();
        cameraFrame1.rotation.RotateAboutSide(1.57079637f);
        cameraFrame1.rotation.RotateAboutForward(this.CameraBearing);
        cameraFrame1.rotation.RotateAboutSide(this.CameraElevation);
        cameraFrame1.rotation.RotateAboutUp(a);
        cameraFrame1.origin = this.CombatCamera.Frame.origin;
        this._cameraSpeed *= (float) (1.0 - 5.0 * (double) dt);
        this._cameraSpeed.x = MBMath.ClampFloat(this._cameraSpeed.x, -20f, 20f);
        this._cameraSpeed.y = MBMath.ClampFloat(this._cameraSpeed.y, -20f, 20f);
        this._cameraSpeed.z = MBMath.ClampFloat(this._cameraSpeed.z, -20f, 20f);
        if (Game.Current.CheatMode)
        {
          if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyIncreaseCameraSpeed"))
            this._cameraSpeedMultiplier *= 1.5f;
          if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyDecreaseCameraSpeed"))
            this._cameraSpeedMultiplier *= 0.6666667f;
          if (this.InputManager.IsHotKeyPressed("ResetCameraSpeed"))
            this._cameraSpeedMultiplier = 1f;
          if (this.InputManager.IsControlDown())
          {
            float num2 = this.SceneLayer.Input.GetDeltaMouseScroll() * 0.008333334f;
            if ((double) num2 > 0.0099999997764825821)
              this._cameraSpeedMultiplier *= 1.25f;
            else if ((double) num2 < -0.0099999997764825821)
              this._cameraSpeedMultiplier *= 0.8f;
          }
        }
        float num3 = (float) (10.0 * (double) this._cameraSpeedMultiplier * (this.IsPhotoModeEnabled ? (flag1 ? 0.0 : 0.30000001192092896) : 1.0));
        if (this.Mission.Mode == MissionMode.Deployment)
        {
          float heightAtPosition = scene1.GetGroundHeightAtPosition(cameraFrame1.origin);
          num3 *= MathF.Max(1f, (float) (1.0 + ((double) cameraFrame1.origin.z - (double) heightAtPosition - 5.0) / 10.0));
        }
        if (!this.IsPhotoModeEnabled && this.SceneLayer.Input.IsGameKeyDown(24) || this.IsPhotoModeEnabled && !flag1 && this.SceneLayer.Input.IsHotKeyDown("FasterCamera"))
          num3 *= (float) this._shiftSpeedMultiplier;
        if (!this._cameraSmoothMode)
        {
          this._cameraSpeed.x = 0.0f;
          this._cameraSpeed.y = 0.0f;
          this._cameraSpeed.z = 0.0f;
        }
        if ((!this.InputManager.IsControlDown() ? 0 : (this.InputManager.IsAltDown() ? 1 : 0)) == 0 && !this.LockCameraMovement)
        {
          int num4 = !this._isGamepadActive || this.Mission.Mode != MissionMode.Deployment ? 1 : (Input.IsKeyDown(InputKey.ControllerLTrigger) ? 1 : 0);
          Vec3 zero = Vec3.Zero;
          if (num4 != 0)
          {
            zero.x = this.SceneLayer.Input.GetGameKeyAxis("MovementAxisX");
            zero.y = this.SceneLayer.Input.GetGameKeyAxis("MovementAxisY");
            if ((double) MathF.Abs(zero.x) < 0.20000000298023224)
              zero.x = 0.0f;
            if ((double) MathF.Abs(zero.y) < 0.20000000298023224)
              zero.y = 0.0f;
          }
          if (!this._isGamepadActive || !this.IsPhotoModeEnabled && this.Mission.Mode != MissionMode.Deployment && !this.IsOrderMenuOpen && !this.IsTransferMenuOpen)
          {
            if (this.SceneLayer.Input.IsGameKeyDown(14))
              ++zero.z;
            if (this.SceneLayer.Input.IsGameKeyDown(15))
              --zero.z;
          }
          else if (this.Mission.Mode == MissionMode.Deployment && this.SceneLayer.IsHitThisFrame)
          {
            if (this.SceneLayer.Input.IsKeyDown(InputKey.ControllerRBumper))
              ++zero.z;
            if (this.SceneLayer.Input.IsKeyDown(InputKey.ControllerLBumper))
              --zero.z;
          }
          if (zero.IsNonZero)
          {
            float val2 = zero.Normalize();
            zero *= num3 * Math.Min(1f, val2);
            this._cameraSpeed += zero;
          }
        }
        if (this.Mission.Mode == MissionMode.Deployment && !this.IsRadialMenuActive)
        {
          cameraFrame1.origin += this._cameraSpeed.x * new Vec3(cameraFrame1.rotation.s.AsVec2).NormalizedCopy() * dt;
          cameraFrame1.origin -= this._cameraSpeed.y * new Vec3(cameraFrame1.rotation.u.AsVec2).NormalizedCopy() * dt;
          cameraFrame1.origin.z += this._cameraSpeed.z * dt;
          if ((!Game.Current.CheatMode ? 0 : (this.InputManager.IsControlDown() ? 1 : 0)) == 0)
          {
            this._cameraDeploymentHeightToAdd += (float) (3.0 * (double) this.SceneLayer.Input.GetDeltaMouseScroll() / 120.0);
            if (this.SceneLayer.Input.IsHotKeyDown("DeploymentCameraIsActive"))
              this._cameraDeploymentHeightToAdd += 0.05f * Input.MouseMoveY;
          }
          if ((double) MathF.Abs(this._cameraDeploymentHeightToAdd) > 1.0 / 1000.0)
          {
            cameraFrame1.origin.z += (float) ((double) this._cameraDeploymentHeightToAdd * (double) dt * 10.0);
            this._cameraDeploymentHeightToAdd = MathF.Lerp(this._cameraDeploymentHeightToAdd, 0.0f, 1f - MathF.Pow(0.0005f, dt));
          }
          else
          {
            cameraFrame1.origin.z += this._cameraDeploymentHeightToAdd;
            this._cameraDeploymentHeightToAdd = 0.0f;
          }
        }
        else
        {
          cameraFrame1.origin += this._cameraSpeed.x * cameraFrame1.rotation.s * dt;
          cameraFrame1.origin -= this._cameraSpeed.y * cameraFrame1.rotation.u * dt;
          cameraFrame1.origin += this._cameraSpeed.z * cameraFrame1.rotation.f * dt;
        }
        if (!MBEditor.IsEditModeOn)
        {
          if (!this.Mission.IsPositionInsideBoundaries(cameraFrame1.origin.AsVec2))
            cameraFrame1.origin.AsVec2 = this.Mission.GetClosestBoundaryPosition(cameraFrame1.origin.AsVec2);
          if (!GameNetwork.IsMultiplayer && this.Mission.Mode == MissionMode.Deployment)
          {
            BattleSideEnum side = this.Mission.PlayerTeam.Side;
            IMissionDeploymentPlan deploymentPlan = this.Mission.DeploymentPlan;
            if (deploymentPlan.HasDeploymentBoundaries(side))
            {
              IMissionDeploymentPlan missionDeploymentPlan1 = deploymentPlan;
              int battleSide1 = (int) side;
              Vec2 asVec2 = cameraFrame1.origin.AsVec2;
              ref Vec2 local1 = ref asVec2;
              if (!missionDeploymentPlan1.IsPositionInsideDeploymentBoundaries((BattleSideEnum) battleSide1, in local1))
              {
                ref Vec3 local2 = ref cameraFrame1.origin;
                IMissionDeploymentPlan missionDeploymentPlan2 = deploymentPlan;
                int battleSide2 = (int) side;
                asVec2 = cameraFrame1.origin.AsVec2;
                ref Vec2 local3 = ref asVec2;
                Vec2 boundaryPosition = missionDeploymentPlan2.GetClosestDeploymentBoundaryPosition((BattleSideEnum) battleSide2, in local3);
                local2.AsVec2 = boundaryPosition;
              }
            }
          }
          float heightAtPosition = scene1.GetGroundHeightAtPosition(this.Mission.Mode == MissionMode.Deployment ? cameraFrame1.origin + new Vec3(z: 100f) : cameraFrame1.origin);
          if (!this.IsCheatGhostMode && (double) heightAtPosition < 9999.0)
            cameraFrame1.origin.z = MathF.Max(cameraFrame1.origin.z, heightAtPosition + 0.5f);
          if ((double) cameraFrame1.origin.z > (double) heightAtPosition + 80.0)
            cameraFrame1.origin.z = heightAtPosition + 80f;
          if ((double) this._cameraHeightLimit > 0.0 && (double) cameraFrame1.origin.z > (double) this._cameraHeightLimit)
            cameraFrame1.origin.z = this._cameraHeightLimit;
          if ((double) cameraFrame1.origin.z < -100.0)
            cameraFrame1.origin.z = -100f;
        }
      }
      else if (flag2 && !this.IsPhotoModeEnabled)
      {
        Agent agent = agentToFollow;
        if ((NativeObject) agentToFollow.AgentVisuals != (NativeObject) null)
        {
          if (this._cameraAddSpecialMovement)
          {
            if ((this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject != null && this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType == FocusableObjectType.Agent)
            {
              Vec3 vec3 = (this._missionMainAgentController.InteractionComponent.CurrentFocusedObject as Agent).Position - agentToFollow.Position;
              this._cameraSpecialTargetFOV = 65.0 / (double) this.CameraViewAngle * (double) MathF.Abs(vec3.z) < 2.0 ? MathF.Min(this.Mission.Mode == MissionMode.Barter ? 48.75f : 32.5f, (this.Mission.Mode == MissionMode.Barter ? 75f : 50f) / vec3.AsVec2.Length) : 160f / vec3.AsVec2.Length;
            }
            else
              this._cameraSpecialTargetFOV = 65f;
            if (flag3)
              this._cameraSpecialCurrentFOV = this._cameraSpecialTargetFOV;
          }
          MatrixFrame boneEntitialFrame1 = agentToFollow.AgentVisuals.GetBoneEntitialFrame(agentToFollow.Monster.ThoraxLookDirectionBoneIndex, true);
          MatrixFrame boneEntitialFrame2 = agentToFollow.AgentVisuals.GetBoneEntitialFrame(agentToFollow.Monster.HeadLookDirectionBoneIndex, true);
          boneEntitialFrame2.origin = boneEntitialFrame2.TransformToParent(agent.Monster.FirstPersonCameraOffsetWrtHead);
          MatrixFrame frame = agentToFollow.AgentVisuals.GetFrame();
          Vec3 parent1 = frame.TransformToParent(boneEntitialFrame2.origin);
          bool flag4 = (this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject != null && this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType == FocusableObjectType.Agent;
          if ((agent.GetCurrentAnimationFlag(0) & AnimFlags.anf_lock_camera) != (AnimFlags) 0 || (agent.GetCurrentAnimationFlag(1) & AnimFlags.anf_lock_camera) != (AnimFlags) 0)
          {
            MatrixFrame parent2 = frame.TransformToParent(boneEntitialFrame2);
            parent2.rotation.MakeUnit();
            this.CameraBearing = parent2.rotation.f.RotationZ;
            this.CameraElevation = parent2.rotation.f.RotationX;
          }
          else if (flag4 || agentToFollow.IsMainAgent && this._missionMainAgentController != null && this._missionMainAgentController.CustomLookDir.IsNonZero)
          {
            Vec3 vb;
            if (flag4)
            {
              Agent currentFocusedObject = this._missionMainAgentController.InteractionComponent.CurrentFocusedObject as Agent;
              closestPoint1 = currentFocusedObject.Position;
              closestPoint1 = new Vec3(closestPoint1.AsVec2, currentFocusedObject.AgentVisuals.GetGlobalStableEyePoint(currentFocusedObject.IsHuman).z) - parent1;
              Vec3 vec3 = closestPoint1.NormalizedCopy();
              closestPoint1 = new Vec3(vec3.y, -vec3.x);
              Vec3 vec = closestPoint1.NormalizedCopy();
              vb = vec3.RotateAboutAnArbitraryVector(vec, (this.Mission.Mode == MissionMode.Conversation ? -3f / 1000f : -0.0045f) * this._cameraSpecialCurrentFOV);
            }
            else
              vb = this._missionMainAgentController.CustomLookDir;
            if (flag3)
            {
              this.CameraBearing = vb.RotationZ;
              this.CameraElevation = vb.RotationX;
            }
            else
            {
              Mat3 identity = Mat3.Identity;
              identity.RotateAboutUp(this.CameraBearing);
              identity.RotateAboutSide(this.CameraElevation);
              Vec3 f = identity.f;
              Vec3 vec = Vec3.CrossProduct(f, vb);
              float num5 = vec.Normalize();
              Vec3 vec3 = (double) num5 >= 9.9999997473787516E-05 ? f.RotateAboutAnArbitraryVector(vec, (float) ((double) num5 * (double) dt * 5.0)) : vb;
              this.CameraBearing = vec3.RotationZ;
              this.CameraElevation = vec3.RotationX;
            }
          }
          else
          {
            float num6 = MBMath.WrapAngle(this.CameraBearing);
            float num7 = MBMath.WrapAngle(this.CameraElevation);
            float newBearing;
            float newElevation;
            this.CalculateNewBearingAndElevationForFirstPerson(agentToFollow, num6, num7, out newBearing, out newElevation);
            this.CameraBearing = MBMath.LerpRadians(num6, newBearing, Math.Min(dt * 12f, 1f), 1E-05f, 0.5f);
            this.CameraElevation = MBMath.LerpRadians(num7, newElevation, Math.Min(dt * 12f, 1f), 1E-05f, 0.5f);
          }
          cameraFrame1.rotation.RotateAboutSide(1.57079637f);
          cameraFrame1.rotation.RotateAboutForward(this.CameraBearing);
          cameraFrame1.rotation.RotateAboutSide(this.CameraElevation);
          float actionChannelWeight = agentToFollow.GetActionChannelWeight(1);
          float f1 = MBMath.WrapAngle(this.CameraBearing - agentToFollow.MovementDirectionAsAngle);
          float amount = (float) (1.0 - (1.0 - (double) actionChannelWeight) * (double) MBMath.ClampFloat((float) (((double) MathF.Abs(f1) - 1.0) * 0.6600000262260437), 0.0f, 1f));
          float num8 = 0.25f;
          float num9 = 0.15f;
          float num10 = 0.15f;
          Vec3 vec3_1 = frame.rotation.u * num8;
          Vec3 vec3_2 = frame.rotation.u * num9 + Vec3.Forward * num10;
          vec3_2.RotateAboutX(MBMath.ClampFloat(this.CameraElevation, -0.35f, 0.35f));
          vec3_2.RotateAboutZ(this.CameraBearing);
          Vec3 vec3_3 = frame.TransformToParent(boneEntitialFrame1.origin) + vec3_1 + vec3_2;
          if ((double) actionChannelWeight > 0.0)
          {
            this._currentViewBlockingBodyCoeff = this._targetViewBlockingBodyCoeff = 1f;
            this._applySmoothTransitionToVirtualEyeCamera = true;
          }
          else
          {
            closestPoint1 = parent1 - vec3_3;
            Vec3 v2 = closestPoint1.NormalizedCopy();
            if ((double) Vec3.DotProduct(cameraFrame1.rotation.u, v2) > 0.0)
              v2 = -v2;
            float num11 = 0.974999964f;
            float num12 = MathF.Lerp(0.55f, 0.7f, MathF.Abs(cameraFrame1.rotation.u.z));
            float collisionDistance;
            if (this.Mission.Scene.RayCastForClosestEntityOrTerrain(parent1 - v2 * (num11 * num12), parent1 + v2 * (num11 * (1f - num12)), out collisionDistance, out closestPoint1, out collidedEntity, excludeBodyFlags: BodyFlags.CameraCollisionRayCastExludeFlags | BodyFlags.DontCollideWithCamera))
            {
              float num13 = (float) (((double) num11 - (double) collisionDistance) / 0.064999997615814209);
              this._targetViewBlockingBodyCoeff = 1f / MathF.Max(1f, num13 * num13 * num13);
            }
            else
              this._targetViewBlockingBodyCoeff = 1f;
            if ((double) this._currentViewBlockingBodyCoeff < (double) this._targetViewBlockingBodyCoeff)
              this._currentViewBlockingBodyCoeff = MathF.Min(this._currentViewBlockingBodyCoeff + dt * 12f, this._targetViewBlockingBodyCoeff);
            else if ((double) this._currentViewBlockingBodyCoeff > (double) this._targetViewBlockingBodyCoeff)
              this._currentViewBlockingBodyCoeff = !this._applySmoothTransitionToVirtualEyeCamera ? this._targetViewBlockingBodyCoeff : MathF.Max(this._currentViewBlockingBodyCoeff - dt * 6f, this._targetViewBlockingBodyCoeff);
            else
              this._applySmoothTransitionToVirtualEyeCamera = false;
            amount *= this._currentViewBlockingBodyCoeff;
          }
          cameraFrame1.origin.x = MBMath.Lerp(vec3_3.x, parent1.x, amount);
          cameraFrame1.origin.y = MBMath.Lerp(vec3_3.y, parent1.y, amount);
          cameraFrame1.origin.z = MBMath.Lerp(vec3_3.z, parent1.z, actionChannelWeight);
        }
        else
          cameraFrame1 = this.CombatCamera.Frame;
      }
      else
      {
        float num14 = 0.6f;
        float num15 = 0.0f;
        int num16 = agentVisualToFollow != null ? 1 : 0;
        float num17 = 1f;
        bool flag5 = false;
        float num18;
        float num19;
        if (num16 != 0)
        {
          this._cameraSpecialTargetAddedBearing = 0.0f;
          this._cameraSpecialTargetAddedElevation = 0.0f;
          this._cameraSpecialTargetPositionToAdd = Vec3.Zero;
          this._cameraSpecialTargetDistanceToAdd = 0.0f;
          num18 = 1.25f;
          flag3 = flag3 || agentVisualToFollow != this.LastFollowedAgentVisuals;
          if (agentVisualToFollow.GetEquipment().Horse.Item != null)
          {
            float num20 = (float) agentVisualToFollow.GetEquipment().Horse.Item.HorseComponent.BodyLength * 0.01f;
            num18 += 2f;
            num19 = (float) (1.0 * (double) num20 + 0.89999997615814209 * (double) num17 - 0.20000000298023224);
          }
          else
            num19 = 1f * num17;
          this.CameraBearing = MBMath.WrapAngle(agentVisualToFollow.GetFrame().rotation.f.RotationZ + 3.14159274f);
          this.CameraElevation = 0.15f;
        }
        else
        {
          flag5 = agentToFollow.HasMount;
          num17 = agentToFollow.AgentScale;
          flag3 = flag3 || agentToFollow != this.LastFollowedAgent;
          if ((this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject != null && this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType == FocusableObjectType.Agent)
          {
            Agent currentFocusedObject = this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject as Agent;
            num19 = (float) (((double) currentFocusedObject.AgentVisuals.GetGlobalStableEyePoint(true).z + (double) agentToFollow.AgentVisuals.GetGlobalStableEyePoint(true).z) * 0.5) - agentToFollow.Position.z;
            if (currentFocusedObject.HasMount)
              num14 += 0.1f;
            if (this.Mission.Mode == MissionMode.Barter)
            {
              closestPoint1 = currentFocusedObject.Position;
              Vec2 asVec2_1 = closestPoint1.AsVec2;
              closestPoint1 = agentToFollow.Position;
              Vec2 asVec2_2 = closestPoint1.AsVec2;
              Vec2 vec2_1 = asVec2_1 - asVec2_2;
              float length = vec2_1.Length;
              float num21 = (float) ((double) MathF.Max(num14 + Mission.CameraAddedDistance, 0.48f) * (double) num17 + (double) length * 0.5);
              num19 += -0.004f * num21 * this._cameraSpecialCurrentFOV;
              Vec3 globalStableEyePoint1 = currentFocusedObject.AgentVisuals.GetGlobalStableEyePoint(currentFocusedObject.IsHuman);
              Vec3 globalStableEyePoint2 = agentToFollow.AgentVisuals.GetGlobalStableEyePoint(agentToFollow.IsHuman);
              this._cameraSpecialTargetAddedBearing = MBMath.WrapAngle(vec2_1.RotationInRadians - MathF.Min(0.471238941f, 0.4f / length) - this.CameraBearing);
              Vec2 vec2_2 = new Vec2(globalStableEyePoint1.z - globalStableEyePoint2.z, MathF.Max(length, 1f));
              this._cameraSpecialTargetAddedElevation = (flag5 ? -0.03f : 0.0f) - vec2_2.RotationInRadians - this.CameraElevation + MathF.Asin((float) (-0.20000000298023224 * ((double) num21 - (double) length * 0.5)) / num21);
            }
          }
          else if (flag5)
          {
            num14 += 0.1f;
            Agent mountAgent = agentToFollow.MountAgent;
            Monster monster = mountAgent.Monster;
            num19 = (float) (((double) monster.RiderCameraHeightAdder + (double) monster.BodyCapsulePoint1.z + (double) monster.BodyCapsuleRadius) * (double) mountAgent.AgentScale + (double) agentToFollow.Monster.CrouchEyeHeight * (double) num17);
          }
          else
            num19 = agentToFollow.AgentVisuals.GetCurrentRagdollState() != RagdollState.Active ? ((agentToFollow.GetCurrentAnimationFlag(0) & AnimFlags.anf_reset_camera_height) == (AnimFlags) 0 ? (agentToFollow.CrouchMode || agentToFollow.IsSitting() ? (agentToFollow.Monster.CrouchEyeHeight + 0.2f) * num17 : (agentToFollow.Monster.StandingEyeHeight + 0.2f) * num17) : 0.5f) : 0.5f;
          if ((!this.IsViewingCharacter() ? 0 : (cameraType != SpectatorCameraTypes.LockToTeamMembersView ? 1 : (agentToFollow == this.Mission.MainAgent ? 1 : 0))) != 0 || this.IsPhotoModeEnabled)
          {
            num19 *= 0.5f;
            num14 += 0.5f;
          }
          else if (agentToFollow.HasMount && agentToFollow.IsDoingPassiveAttack && (cameraType != SpectatorCameraTypes.LockToTeamMembersView || agentToFollow == this.Mission.MainAgent))
            num19 *= 1.1f;
          if (this._cameraAddSpecialMovement)
          {
            if ((this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject != null && this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType == FocusableObjectType.Agent)
            {
              Agent currentFocusedObject = this._missionMainAgentController.InteractionComponent.CurrentFocusedObject as Agent;
              Vec3 globalStableEyePoint3 = currentFocusedObject.AgentVisuals.GetGlobalStableEyePoint(true);
              Vec3 globalStableEyePoint4 = agentToFollow.AgentVisuals.GetGlobalStableEyePoint(true);
              closestPoint1 = currentFocusedObject.Position;
              Vec2 asVec2_3 = closestPoint1.AsVec2;
              closestPoint1 = agentToFollow.Position;
              Vec2 asVec2_4 = closestPoint1.AsVec2;
              Vec2 vec2_3 = asVec2_3 - asVec2_4;
              float length = vec2_3.Length;
              this._cameraSpecialTargetPositionToAdd = new Vec3(vec2_3 * 0.5f);
              this._cameraSpecialTargetDistanceToAdd = length * (flag5 ? 1.3f : 0.8f) - num14;
              this._cameraSpecialTargetAddedBearing = MBMath.WrapAngle(vec2_3.RotationInRadians - MathF.Min(0.471238941f, 0.48f / length) - this.CameraBearing);
              Vec2 vec2_4 = new Vec2(globalStableEyePoint3.z - globalStableEyePoint4.z, MathF.Max(length, 1f));
              this._cameraSpecialTargetAddedElevation = (flag5 ? -0.03f : 0.0f) - vec2_4.RotationInRadians - this.CameraElevation;
              this._cameraSpecialTargetFOV = MathF.Min(32.5f, 50f / length);
            }
            else
            {
              this._cameraSpecialTargetPositionToAdd = Vec3.Zero;
              this._cameraSpecialTargetDistanceToAdd = 0.0f;
              this._cameraSpecialTargetAddedBearing = 0.0f;
              this._cameraSpecialTargetAddedElevation = 0.0f;
              this._cameraSpecialTargetFOV = 65f;
            }
            if (flag3)
            {
              this._cameraSpecialCurrentPositionToAdd = this._cameraSpecialTargetPositionToAdd;
              this._cameraSpecialCurrentDistanceToAdd = this._cameraSpecialTargetDistanceToAdd;
              this._cameraSpecialCurrentAddedBearing = this._cameraSpecialTargetAddedBearing;
              this._cameraSpecialCurrentAddedElevation = this._cameraSpecialTargetAddedElevation;
              this._cameraSpecialCurrentFOV = this._cameraSpecialTargetFOV;
            }
          }
          if ((double) this._cameraSpecialCurrentDistanceToAdd != (double) this._cameraSpecialTargetDistanceToAdd)
          {
            float f = this._cameraSpecialTargetDistanceToAdd - this._cameraSpecialCurrentDistanceToAdd;
            if (flag3 || (double) MathF.Abs(f) < 9.9999997473787516E-05)
              this._cameraSpecialCurrentDistanceToAdd = this._cameraSpecialTargetDistanceToAdd;
            else
              this._cameraSpecialCurrentDistanceToAdd += f * 4f * dt;
          }
          num18 = num14 + this._cameraSpecialCurrentDistanceToAdd;
        }
        if (flag3)
          this._cameraTargetAddedHeight = num19;
        else
          this._cameraTargetAddedHeight += (float) (((double) num19 - (double) this._cameraTargetAddedHeight) * (double) dt * 6.0) * num17;
        if ((double) this._cameraSpecialTargetAddedBearing != (double) this._cameraSpecialCurrentAddedBearing)
        {
          float f = this._cameraSpecialTargetAddedBearing - this._cameraSpecialCurrentAddedBearing;
          if (flag3 || (double) MathF.Abs(f) < 9.9999997473787516E-05)
            this._cameraSpecialCurrentAddedBearing = this._cameraSpecialTargetAddedBearing;
          else
            this._cameraSpecialCurrentAddedBearing += f * 10f * dt;
        }
        if ((double) this._cameraSpecialTargetAddedElevation != (double) this._cameraSpecialCurrentAddedElevation)
        {
          float f = this._cameraSpecialTargetAddedElevation - this._cameraSpecialCurrentAddedElevation;
          if (flag3 || (double) MathF.Abs(f) < 9.9999997473787516E-05)
            this._cameraSpecialCurrentAddedElevation = this._cameraSpecialTargetAddedElevation;
          else
            this._cameraSpecialCurrentAddedElevation += f * 8f * dt;
        }
        cameraFrame1.rotation.RotateAboutSide(1.57079637f);
        if (agentToFollow != null && !agentToFollow.IsMine && cameraType == SpectatorCameraTypes.LockToTeamMembersView)
        {
          Vec3 lookDirection = agentToFollow.LookDirection;
          cameraFrame1.rotation.RotateAboutForward(lookDirection.AsVec2.RotationInRadians);
          cameraFrame1.rotation.RotateAboutSide(MathF.Asin(lookDirection.z));
        }
        else
        {
          cameraFrame1.rotation.RotateAboutForward(this.CameraBearing + this._cameraSpecialCurrentAddedBearing);
          cameraFrame1.rotation.RotateAboutSide(this.CameraElevation + this._cameraSpecialCurrentAddedElevation);
          if (this.IsPhotoModeEnabled)
          {
            float a = -scene1.GetPhotoModeRoll();
            cameraFrame1.rotation.RotateAboutUp(a);
          }
        }
        MatrixFrame matrixFrame = cameraFrame1;
        float num22 = MathF.Max(num18 + Mission.CameraAddedDistance, 0.48f) * num17;
        if (this.Mission.Mode != MissionMode.Conversation && this.Mission.Mode != MissionMode.Barter && agentToFollow != null && agentToFollow.IsActive() && BannerlordConfig.EnableVerticalAimCorrection)
        {
          MissionWeapon wieldedWeapon = agentToFollow.WieldedWeapon;
          WeaponComponentData currentUsageItem = wieldedWeapon.CurrentUsageItem;
          if (currentUsageItem != null && currentUsageItem.IsRangedWeapon)
          {
            MatrixFrame frame = this.CombatCamera.Frame;
            frame.rotation.RotateAboutSide(-this._cameraAddedElevation);
            float num23;
            if (flag5)
            {
              Agent mountAgent = agentToFollow.MountAgent;
              Monster monster = mountAgent.Monster;
              num23 = (float) (((double) monster.RiderCameraHeightAdder + (double) monster.BodyCapsulePoint1.z + (double) monster.BodyCapsuleRadius) * (double) mountAgent.AgentScale + (double) agentToFollow.Monster.CrouchEyeHeight * (double) num17);
            }
            else
              num23 = agentToFollow.Monster.StandingEyeHeight * num17;
            if (currentUsageItem.WeaponFlags.HasAnyFlag<WeaponFlags>(WeaponFlags.UseHandAsThrowBase))
              num23 *= 1.25f;
            float num24;
            if (flag3)
            {
              Vec3 vec3_4 = agentToFollow.Position + cameraFrame1.rotation.f * num17 * (0.7f * MathF.Pow(MathF.Cos((float) (1.0 / (((double) num22 / (double) num17 - 0.20000000298023224) * 30.0 + 20.0))), 3500f));
              vec3_4.z += this._cameraTargetAddedHeight;
              Vec3 vec3_5 = vec3_4 + cameraFrame1.rotation.u * num22;
              double z = (double) vec3_5.z;
              double num25 = -(double) matrixFrame.rotation.u.z;
              Vec2 asVec2_5 = vec3_5.AsVec2;
              closestPoint1 = agentToFollow.Position;
              Vec2 asVec2_6 = closestPoint1.AsVec2;
              double length = (double) (asVec2_5 - asVec2_6).Length;
              double num26 = num25 * length;
              num24 = (float) (z + num26 - ((double) agentToFollow.Position.z + (double) num23));
            }
            else
            {
              double z = (double) frame.origin.z;
              double num27 = -(double) frame.rotation.u.z;
              Vec2 asVec2_7 = frame.origin.AsVec2;
              closestPoint1 = agentToFollow.Position;
              Vec2 asVec2_8 = closestPoint1.AsVec2;
              double length = (double) (asVec2_7 - asVec2_8).Length;
              double num28 = num27 * length;
              num24 = (float) (z + num28 - ((double) agentToFollow.Position.z + (double) num23));
            }
            if ((double) num24 > 0.0)
            {
              double num29 = (double) MathF.Sqrt(19.6f * num24);
              wieldedWeapon = agentToFollow.WieldedWeapon;
              double speedForCurrentUsage = (double) wieldedWeapon.GetModifiedMissileSpeedForCurrentUsage();
              num15 = MathF.Max(-0.15f, (float) -(double) MathF.Asin(MathF.Min(1f, (float) (num29 / speedForCurrentUsage))));
            }
            else
              num15 = 0.0f;
          }
          else
            num15 = ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.MeleeAddedElevationForCrosshair);
        }
        if (flag3 || this.IsPhotoModeEnabled)
          this._cameraAddedElevation = num15;
        else
          this._cameraAddedElevation += (float) (((double) num15 - (double) this._cameraAddedElevation) * (double) dt * 3.0);
        if (!this.IsPhotoModeEnabled)
          cameraFrame1.rotation.RotateAboutSide(this._cameraAddedElevation);
        bool flag6 = this.IsViewingCharacter() && !GameNetwork.IsSessionActive;
        bool flag7 = agentToFollow != null && (NativeObject) agentToFollow.AgentVisuals != (NativeObject) null && agentToFollow.AgentVisuals.GetCurrentRagdollState() != 0;
        bool flag8 = agentToFollow != null && agentToFollow.IsActive() && agentToFollow.GetCurrentActionType(0) == Agent.ActionCodeType.Mount;
        Vec2 vec2 = Vec2.Zero;
        Vec3 vec3_6;
        Vec3 vec3_7;
        if (num16 != 0)
        {
          MBAgentVisuals visuals = this.GetPlayerAgentVisuals(component).GetVisuals();
          vec3_6 = visuals != null ? visuals.GetGlobalFrame().origin : component.ControlledAgent.Position;
          vec3_7 = vec3_6;
        }
        else
        {
          vec3_6 = agentToFollow.VisualPosition;
          vec3_7 = flag7 ? agentToFollow.AgentVisuals.GetFrame().origin : vec3_6;
          if (flag5)
          {
            vec2 = agentToFollow.MountAgent.GetMovementDirection() * agentToFollow.MountAgent.Monster.RiderBodyCapsuleForwardAdder;
            vec3_7 += vec2.ToVec3();
          }
        }
        if (this._cameraAddSpecialPositionalMovement)
        {
          Vec3 vec3_8 = matrixFrame.rotation.f * num17 * (0.7f * MathF.Pow(MathF.Cos((float) (1.0 / (((double) num22 / (double) num17 - 0.20000000298023224) * 30.0 + 20.0))), 3500f));
          if (this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter)
            this._cameraSpecialCurrentPositionToAdd += vec3_8;
          else
            this._cameraSpecialCurrentPositionToAdd -= vec3_8;
        }
        if (this._cameraSpecialCurrentPositionToAdd != this._cameraSpecialTargetPositionToAdd)
        {
          Vec3 vec3_9 = this._cameraSpecialTargetPositionToAdd - this._cameraSpecialCurrentPositionToAdd;
          if (flag3 || (double) vec3_9.LengthSquared < 1.0000001111620804E-06)
            this._cameraSpecialCurrentPositionToAdd = this._cameraSpecialTargetPositionToAdd;
          else
            this._cameraSpecialCurrentPositionToAdd += vec3_9 * 4f * dt;
        }
        Vec3 vec3_10 = vec3_6 + this._cameraSpecialCurrentPositionToAdd;
        Vec3 vec3_11 = vec3_7 + this._cameraSpecialCurrentPositionToAdd;
        vec3_11.z += this._cameraTargetAddedHeight;
        int num30 = 0;
        bool castSupportRay = agentToFollow != null;
        Vec3 supportRaycastPoint = castSupportRay ? (flag5 ? agentToFollow.MountAgent.GetChestGlobalPosition() : agentToFollow.GetChestGlobalPosition()) : Vec3.Invalid;
        bool flag9;
        do
        {
          Vec3 vec3_12 = vec3_11;
          if (this.Mission.Mode != MissionMode.Conversation && this.Mission.Mode != MissionMode.Barter)
            vec3_12 += matrixFrame.rotation.f * num17 * (0.7f * MathF.Pow(MathF.Cos((float) (1.0 / (((double) num22 / (double) num17 - 0.20000000298023224) * 30.0 + 20.0))), 3500f));
          Vec3 o = vec3_12 + matrixFrame.rotation.u * num22;
          if (flag7 | flag8)
          {
            float num31 = 0.0f;
            if (flag8)
            {
              double currentActionProgress = (double) agentToFollow.GetCurrentActionProgress(0);
              num31 = (float) (currentActionProgress * currentActionProgress * 20.0);
            }
            vec3_12 = this._cameraTarget + (vec3_12 - this._cameraTarget) * (5f + num31) * dt;
          }
          flag9 = false;
          MatrixFrame cameraFrame2 = new MatrixFrame(cameraFrame1.rotation, o);
          Camera.GetNearPlanePointsStatic(ref cameraFrame2, this.IsPhotoModeEnabled ? num1 * ((float) Math.PI / 180f) : this.CameraViewAngle * ((float) Math.PI / 180f), Screen.AspectRatio, 0.2f, 1f, this._cameraNearPlanePoints);
          Vec3 zero = Vec3.Zero;
          for (int index = 0; index < 4; ++index)
            zero += this._cameraNearPlanePoints[index];
          Vec3 vec3_13 = zero * 0.25f;
          Vec3 centerPoint = new Vec3(vec3_10.AsVec2 + vec2, vec3_12.z);
          Vec3 vec3_14 = centerPoint - vec3_13;
          for (int index = 0; index < 4; ++index)
            this._cameraNearPlanePoints[index] += vec3_14;
          this._cameraBoxPoints[0] = this._cameraNearPlanePoints[3] + cameraFrame2.rotation.u * 0.01f;
          this._cameraBoxPoints[1] = this._cameraNearPlanePoints[0];
          this._cameraBoxPoints[2] = this._cameraNearPlanePoints[3];
          this._cameraBoxPoints[3] = this._cameraNearPlanePoints[2];
          this._cameraBoxPoints[4] = this._cameraNearPlanePoints[1] + cameraFrame2.rotation.u * 0.01f;
          this._cameraBoxPoints[5] = this._cameraNearPlanePoints[0] + cameraFrame2.rotation.u * 0.01f;
          this._cameraBoxPoints[6] = this._cameraNearPlanePoints[1];
          this._cameraBoxPoints[7] = this._cameraNearPlanePoints[2] + cameraFrame2.rotation.u * 0.01f;
          float num32 = ((!this.IsPhotoModeEnabled ? 0 : (!flag1 ? 1 : 0)) & (photoModeOrbit ? 1 : 0)) != 0 ? this._zoomAmount : 0.0f;
          num22 += num32;
          float collisionDistance;
          Vec3 closestPoint2;
          if (scene1.BoxCastOnlyForCamera(this._cameraBoxPoints, centerPoint, castSupportRay, supportRaycastPoint, cameraFrame2.rotation.u, num22 + 0.5f, out collisionDistance, out closestPoint2, out collidedEntity))
          {
            collisionDistance = MathF.Max(Vec3.DotProduct(cameraFrame2.rotation.u, closestPoint2 - vec3_12), 0.48f * num17);
            if ((double) collisionDistance < (double) num22)
            {
              flag9 = true;
              num22 = collisionDistance;
            }
          }
          ++num30;
        }
        while (((flag6 ? 0 : (num30 < 5 ? 1 : 0)) & (flag9 ? 1 : 0)) != 0);
        float num33 = num22 - Mission.CameraAddedDistance;
        if (flag3 || (double) this.CameraResultDistanceToTarget > (double) num22 && num30 > 1)
        {
          this.CameraResultDistanceToTarget = num22;
        }
        else
        {
          float maxValue = MathF.Max(MathF.Abs(Mission.CameraAddedDistance - this._lastCameraAddedDistance) * num17, MathF.Abs((float) (((double) num33 - ((double) this.CameraResultDistanceToTarget - (double) this._lastCameraAddedDistance)) * (double) dt * 3.0) * num17));
          this.CameraResultDistanceToTarget += MBMath.ClampFloat(num22 - this.CameraResultDistanceToTarget, -maxValue, maxValue);
        }
        this._lastCameraAddedDistance = Mission.CameraAddedDistance;
        this._cameraTarget = vec3_11;
        if (this.Mission.Mode != MissionMode.Conversation && this.Mission.Mode != MissionMode.Barter)
          this._cameraTarget += matrixFrame.rotation.f * num17 * (0.7f * MathF.Pow(MathF.Cos((float) (1.0 / (((double) num22 / (double) num17 - 0.20000000298023224) * 30.0 + 20.0))), 3500f));
        cameraFrame1.origin = this._cameraTarget + matrixFrame.rotation.u * this.CameraResultDistanceToTarget;
      }
      if ((double) this._cameraSpecialCurrentFOV != (double) this._cameraSpecialTargetFOV)
      {
        float f = this._cameraSpecialTargetFOV - this._cameraSpecialCurrentFOV;
        if (flag3 || (double) MathF.Abs(f) < 1.0 / 1000.0)
          this._cameraSpecialCurrentFOV = this._cameraSpecialTargetFOV;
        else
          this._cameraSpecialCurrentFOV += f * 3f * dt;
      }
      float newDNear = this.Mission.CameraIsFirstPerson ? 0.065f : 0.1f;
      this.CombatCamera.Frame = cameraFrame1;
      if (this.IsPhotoModeEnabled)
      {
        float focusEnd = 0.0f;
        float focus = 0.0f;
        float focusStart = 0.0f;
        float exposure = 0.0f;
        bool vignetteOn = false;
        scene1.GetPhotoModeFocus(ref focus, ref focusStart, ref focusEnd, ref exposure, ref vignetteOn);
        scene1.SetDepthOfFieldFocus(focusEnd);
        scene1.SetDepthOfFieldParameters(focus, focusStart, vignetteOn);
      }
      else if ((this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject != null && this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType == FocusableObjectType.Agent)
      {
        Agent currentFocusedObject = this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject as Agent;
        scene1.SetDepthOfFieldParameters(5f, 5f, false);
        Scene scene2 = scene1;
        closestPoint1 = cameraFrame1.origin - currentFocusedObject.AgentVisuals.GetGlobalStableEyePoint(true);
        double length = (double) closestPoint1.Length;
        scene2.SetDepthOfFieldFocus((float) length);
      }
      else if (!this._zoomAmount.ApproximatelyEqualsTo(1f))
      {
        scene1.SetDepthOfFieldParameters(0.0f, 0.0f, false);
        scene1.SetDepthOfFieldFocus(0.0f);
      }
      this.CombatCamera.SetFovVertical(this.IsPhotoModeEnabled ? num1 * ((float) Math.PI / 180f) : (float) ((double) this._cameraSpecialCurrentFOV * ((double) this.CameraViewAngle / 65.0) * (Math.PI / 180.0)), Screen.AspectRatio, newDNear, 12500f);
      this.SceneView.SetCamera(this.CombatCamera);
      Vec3 attenuationPosition = agentToFollow != null ? agentToFollow.GetEyeGlobalPosition() : cameraFrame1.origin;
      this.Mission.SetCameraFrame(ref cameraFrame1, 65f / this.CameraViewAngle, ref attenuationPosition);
      if (this.LastFollowedAgent != null && this.LastFollowedAgent != this.Mission.MainAgent && (agentToFollow == this.Mission.MainAgent || agentToFollow == null))
      {
        MissionScreen.OnSpectateAgentDelegate spectateAgentFocusOut = this.OnSpectateAgentFocusOut;
        if (spectateAgentFocusOut != null)
          spectateAgentFocusOut(this.LastFollowedAgent);
      }
      this.LastFollowedAgent = agentToFollow;
      this.LastFollowedAgentVisuals = agentVisualToFollow;
      this._cameraApplySpecialMovementsInstantly = false;
      this._cameraAddSpecialMovement = false;
      this._cameraAddSpecialPositionalMovement = false;
    }

    public bool IsViewingCharacter()
    {
      return !this.Mission.CameraIsFirstPerson && !this.IsOrderMenuOpen && this.SceneLayer.Input.IsGameKeyDown(25);
    }

    private void SetCameraFrameToMapView()
    {
      MatrixFrame matrixFrame = MatrixFrame.Identity;
      bool flag1 = false;
      if (GameNetwork.IsMultiplayer)
      {
        GameEntity entityWithTag = this.Mission.Scene.FindEntityWithTag("mp_camera_start_pos");
        if ((NativeObject) entityWithTag != (NativeObject) null)
        {
          matrixFrame = entityWithTag.GetGlobalFrame();
          matrixFrame.rotation.Orthonormalize();
          this.CameraBearing = matrixFrame.rotation.f.RotationZ;
          this.CameraElevation = matrixFrame.rotation.f.RotationX - 1.57079637f;
        }
        else
        {
          Debug.FailedAssert("Multiplayer scene does not contain a camera frame", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\Screens\\MissionScreen.cs", nameof (SetCameraFrameToMapView), 2093);
          flag1 = true;
        }
      }
      else if (this.Mission.Mode == MissionMode.Deployment)
      {
        bool flag2 = this.Mission.PlayerTeam.Side == BattleSideEnum.Attacker;
        GameEntity gameEntity = !flag2 ? this.Mission.Scene.FindEntityWithTag("strategyCameraDefender") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker") : this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraDefender");
        if ((NativeObject) gameEntity != (NativeObject) null)
        {
          matrixFrame = gameEntity.GetGlobalFrame();
          this.CameraBearing = matrixFrame.rotation.f.RotationZ;
          this.CameraElevation = matrixFrame.rotation.f.RotationX - 1.57079637f;
        }
        else if (this.Mission.HasSpawnPath)
        {
          float battleSizeOffset = Mission.GetBattleSizeOffset(100, this.Mission.GetInitialSpawnPath());
          matrixFrame = this.Mission.GetBattleSideInitialSpawnPathFrame(flag2 ? BattleSideEnum.Attacker : BattleSideEnum.Defender, battleSizeOffset).ToGroundMatrixFrame();
          matrixFrame.origin.z += 25f;
          matrixFrame.origin -= 25f * matrixFrame.rotation.f;
          this.CameraBearing = matrixFrame.rotation.f.RotationZ;
          this.CameraElevation = -0.7853982f;
        }
        else
          flag1 = true;
      }
      else
        flag1 = true;
      if (flag1)
      {
        Vec3 min = new Vec3(float.MaxValue, float.MaxValue);
        Vec3 max = new Vec3(float.MinValue, float.MinValue);
        if (this.Mission.Boundaries.ContainsKey("walk_area"))
        {
          foreach (Vec2 vec2 in (IEnumerable<Vec2>) this.Mission.Boundaries["walk_area"])
          {
            min.x = MathF.Min(min.x, vec2.x);
            min.y = MathF.Min(min.y, vec2.y);
            max.x = MathF.Max(max.x, vec2.x);
            max.y = MathF.Max(max.y, vec2.y);
          }
        }
        else
          this.Mission.Scene.GetBoundingBox(out min, out max);
        Vec3 position = (min + max) * 0.5f;
        matrixFrame.origin = position;
        matrixFrame.origin.z += 10000f;
        matrixFrame.origin.z = this.Mission.Scene.GetGroundHeightAtPosition(position) + 10f;
      }
      this.CombatCamera.Frame = matrixFrame;
    }

    private bool HandleUserInputDebug()
    {
      bool flag = false;
      if (this.DebugInput.IsHotKeyPressed("MissionScreenHotkeyResetDebugVariables"))
        GameNetwork.ResetDebugVariables();
      if (this.DebugInput.IsHotKeyPressed("FixSkeletons"))
      {
        MBCommon.FixSkeletons();
        MessageManager.DisplayMessage("Skeleton models are reloaded...", 4294901760U);
        flag = true;
      }
      return flag;
    }

    private void HandleUserInput(float dt)
    {
      bool flag1 = false;
      bool flag2 = this._isGamepadActive && this.PhotoModeRequiresMouse;
      if (this.Mission == null || this.Mission.CurrentState == Mission.State.EndingNextFrame)
        return;
      if (!flag1 && Game.Current.CheatMode)
        flag1 = this.HandleUserInputCheatMode(dt);
      if (flag1)
        return;
      float mouseSensitivity = this.SceneLayer.Input.GetMouseSensitivity();
      if (!this.MouseVisible && this.Mission.MainAgent != null && this.Mission.MainAgent.State == AgentState.Active && this.Mission.MainAgent.IsLookRotationInSlowMotion)
        mouseSensitivity *= ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.ReducedMouseSensitivityMultiplier);
      float num1 = dt / 0.0009f;
      float num2 = dt / 0.0009f;
      float num3 = 0.0f;
      float num4 = 0.0f;
      if ((!MBCommon.IsPaused || this.IsPhotoModeEnabled) && !this.IsRadialMenuActive && (double) this._cameraSpecialTargetFOV > 9.0 && this.Mission.Mode != MissionMode.Barter)
      {
        if (this.MouseVisible && !this.SceneLayer.Input.IsKeyDown(InputKey.RightMouseButton))
        {
          if (this.Mission.Mode != MissionMode.Conversation)
          {
            if (this.Mission.Mode == MissionMode.Deployment)
            {
              num3 = num1 * this.SceneLayer.Input.GetGameKeyAxis("CameraAxisX");
              num4 = -num2 * this.SceneLayer.Input.GetGameKeyAxis("CameraAxisY");
            }
            else
            {
              if ((double) this.SceneLayer.Input.GetMousePositionRanged().x <= 0.0099999997764825821)
                num3 = -400f * dt;
              else if ((double) this.SceneLayer.Input.GetMousePositionRanged().x >= 0.99000000953674316)
                num3 = 400f * dt;
              if ((double) this.SceneLayer.Input.GetMousePositionRanged().y <= 0.0099999997764825821)
                num4 = -400f * dt;
              else if ((double) this.SceneLayer.Input.GetMousePositionRanged().y >= 0.99000000953674316)
                num4 = 400f * dt;
            }
          }
        }
        else if (!this.SceneLayer.Input.GetIsMouseActive())
        {
          float gameKeyAxis1 = this.SceneLayer.Input.GetGameKeyAxis("CameraAxisX");
          float gameKeyAxis2 = this.SceneLayer.Input.GetGameKeyAxis("CameraAxisY");
          if ((double) gameKeyAxis1 > 0.89999997615814209 || (double) gameKeyAxis1 < -0.89999997615814209)
            num1 = dt / 0.00045f;
          if ((double) gameKeyAxis2 > 0.89999997615814209 || (double) gameKeyAxis2 < -0.89999997615814209)
            num2 = dt / 0.00045f;
          if (this._zoomToggled)
          {
            num1 *= BannerlordConfig.ZoomSensitivityModifier;
            num2 *= BannerlordConfig.ZoomSensitivityModifier;
          }
          num3 = num1 * this.SceneLayer.Input.GetGameKeyAxis("CameraAxisX") + this.SceneLayer.Input.GetMouseMoveX();
          num4 = -num2 * this.SceneLayer.Input.GetGameKeyAxis("CameraAxisY") + this.SceneLayer.Input.GetMouseMoveY();
          if (this._missionMainAgentController.IsPlayerAiming && (double) NativeOptions.GetConfig(NativeOptions.NativeOptionsType.EnableGyroAssistedAim) == 1.0)
          {
            float config = NativeOptions.GetConfig(NativeOptions.NativeOptionsType.GyroAimSensitivity);
            float gyroX = Input.GetGyroX();
            double gyroY = (double) Input.GetGyroY();
            float gyroZ = Input.GetGyroZ();
            num3 += (float) ((double) config * (double) gyroZ * 12.0 * -1.0);
            num4 += (float) ((double) config * (double) gyroX * 12.0 * -1.0);
          }
        }
        else
        {
          num3 = this.SceneLayer.Input.GetMouseMoveX();
          num4 = this.SceneLayer.Input.GetMouseMoveY();
          if ((double) this._zoomAmount > 0.6600000262260437)
          {
            num3 *= BannerlordConfig.ZoomSensitivityModifier * this._zoomAmount;
            num4 *= BannerlordConfig.ZoomSensitivityModifier * this._zoomAmount;
          }
        }
      }
      if (NativeConfig.EnableEditMode && this.DebugInput.IsHotKeyPressed("MissionScreenHotkeySwitchCameraSmooth"))
      {
        this._cameraSmoothMode = !this._cameraSmoothMode;
        if (this._cameraSmoothMode)
          MessageManager.DisplayMessage("Camera smooth mode Enabled.", uint.MaxValue);
        else
          MessageManager.DisplayMessage("Camera smooth mode Disabled.", uint.MaxValue);
      }
      float num5 = 0.0035f;
      float num6;
      if (this._cameraSmoothMode)
      {
        num5 *= 0.02f;
        num6 = MathF.Max(0.0f, (float) (1.0 - 2.0 * (0.019999999552965164 + (double) dt - 8.0 * ((double) dt * (double) dt))));
      }
      else
        num6 = 0.0f;
      this._cameraBearingDelta *= num6;
      this._cameraElevationDelta *= num6;
      int num7 = GameNetwork.IsSessionActive ? 1 : 0;
      float num8 = num5 * mouseSensitivity;
      float num9 = -num3 * num8;
      float num10 = (NativeConfig.InvertMouse ? num4 : -num4) * num8;
      if (num7 != 0)
      {
        float maxValue = (float) (0.30000001192092896 + 10.0 * (double) dt);
        num9 = MBMath.ClampFloat(num9, -maxValue, maxValue);
        num10 = MBMath.ClampFloat(num10, -maxValue, maxValue);
      }
      this._cameraBearingDelta += num9;
      this._cameraElevationDelta += num10;
      if (num7 != 0)
      {
        float maxValue = (float) (0.30000001192092896 + 10.0 * (double) dt);
        this._cameraBearingDelta = MBMath.ClampFloat(this._cameraBearingDelta, -maxValue, maxValue);
        this._cameraElevationDelta = MBMath.ClampFloat(this._cameraElevationDelta, -maxValue, maxValue);
      }
      Agent agentToFollow = this.GetSpectatingData(this.CombatCamera.Frame.origin).AgentToFollow;
      if (this.Mission.CameraIsFirstPerson && agentToFollow != null && agentToFollow.Controller == Agent.ControllerType.Player && agentToFollow.HasMount && ((double) ManagedOptions.GetConfig(ManagedOptions.ManagedOptionsType.TurnCameraWithHorseInFirstPerson) == 1.0 && !agentToFollow.WieldedWeapon.IsEmpty && agentToFollow.WieldedWeapon.CurrentUsageItem.IsRangedWeapon || (double) ManagedOptions.GetConfig(ManagedOptions.ManagedOptionsType.TurnCameraWithHorseInFirstPerson) == 2.0 && (agentToFollow.WieldedWeapon.IsEmpty || agentToFollow.WieldedWeapon.CurrentUsageItem.IsMeleeWeapon) || (double) ManagedOptions.GetConfig(ManagedOptions.ManagedOptionsType.TurnCameraWithHorseInFirstPerson) == 3.0))
        this._cameraBearingDelta += agentToFollow.MountAgent.GetTurnSpeed() * dt;
      if (this.InputManager.IsGameKeyDown(28))
        Mission.CameraAddedDistance -= 2.1f * dt;
      if (this.InputManager.IsGameKeyDown(29))
        Mission.CameraAddedDistance += 2.1f * dt;
      Mission.CameraAddedDistance = MBMath.ClampFloat(Mission.CameraAddedDistance, 0.7f, 2.4f);
      this._isGamepadActive = !Input.IsMouseActive && Input.IsControllerConnected;
      if (this._isGamepadActive)
      {
        Agent mainAgent = this.Mission.MainAgent;
        int num11;
        if (mainAgent == null)
        {
          num11 = 0;
        }
        else
        {
          bool? isRangedWeapon = mainAgent.WieldedWeapon.CurrentUsageItem?.IsRangedWeapon;
          bool flag3 = true;
          num11 = isRangedWeapon.GetValueOrDefault() == flag3 & isRangedWeapon.HasValue ? 1 : 0;
        }
        if (num11 == 0)
          goto label_56;
      }
      int num12;
      if ((NativeObject) this.CustomCamera == (NativeObject) null)
      {
        num12 = !this.IsRadialMenuActive ? 1 : 0;
        goto label_57;
      }
label_56:
      num12 = 0;
label_57:
      bool flag4 = num12 != 0 || this._forceCanZoom;
      if (flag4)
      {
        float applicationTime = Time.ApplicationTime;
        if (this.SceneLayer.Input.IsHotKeyPressed("ToggleZoom"))
          this._zoomToggleTime = applicationTime;
        if ((double) applicationTime - (double) this._zoomToggleTime > 0.0099999997764825821 && this.SceneLayer.Input.IsHotKeyDown("ToggleZoom"))
        {
          this._zoomToggleTime = float.MaxValue;
          this._zoomToggled = !this._zoomToggled;
        }
      }
      else
        this._zoomToggled = false;
      bool photoModeOrbit = this.Mission.Scene.GetPhotoModeOrbit();
      if (this.IsPhotoModeEnabled)
      {
        if (photoModeOrbit && !flag2)
        {
          this._zoomAmount -= this.SceneLayer.Input.GetDeltaMouseScroll() * (1f / 500f);
          this._zoomAmount = MBMath.ClampFloat(this._zoomAmount, 0.0f, 50f);
        }
      }
      else
      {
        if (agentToFollow != null && agentToFollow.IsMine && (this._zoomToggled || flag4 && this.SceneLayer.Input.IsGameKeyDown(24)))
          this._zoomAmount += 5f * dt;
        else
          this._zoomAmount -= 5f * dt;
        this._zoomAmount = MBMath.ClampFloat(this._zoomAmount, 0.0f, 1f);
      }
      if (!this.IsPhotoModeEnabled)
      {
        if (this._zoomAmount.ApproximatelyEqualsTo(1f))
          this.Mission.Scene.SetDepthOfFieldParameters((float) ((double) this._zoomAmount * 160.0 * 110.0), (float) ((double) this._zoomAmount * 1500.0 * 0.30000001192092896), false);
        else
          this.Mission.Scene.SetDepthOfFieldParameters(0.0f, 0.0f, false);
      }
      float collisionDistance;
      this.Mission.Scene.RayCastForClosestEntityOrTerrain(this.CombatCamera.Position + this.CombatCamera.Direction * this._cameraRayCastOffset, this.CombatCamera.Position + this.CombatCamera.Direction * 3000f, out collisionDistance);
      this.Mission.Scene.SetDepthOfFieldFocus(collisionDistance);
      Agent mainAgent1 = this.Mission.MainAgent;
      if (mainAgent1 != null && !this.IsPhotoModeEnabled)
      {
        if (this._isPlayerAgentAdded)
        {
          this._isPlayerAgentAdded = false;
          if (this.Mission.Mode != MissionMode.Deployment)
          {
            this.CameraBearing = this.Mission.CameraIsFirstPerson ? mainAgent1.LookDirection.RotationZ : mainAgent1.MovementDirectionAsAngle;
            this.CameraElevation = this.Mission.CameraIsFirstPerson ? mainAgent1.LookDirection.RotationX : 0.0f;
            this._cameraSpecialTargetAddedBearing = 0.0f;
            this._cameraSpecialTargetAddedElevation = 0.0f;
            this._cameraSpecialCurrentAddedBearing = 0.0f;
            this._cameraSpecialCurrentAddedElevation = 0.0f;
          }
        }
        if ((double) this.Mission.ClearSceneTimerElapsedTime < 0.0)
          return;
        if ((this.IsViewingCharacter() || this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter || mainAgent1.IsLookDirectionLocked ? 0 : (this._missionMainAgentController?.LockedAgent == null ? 1 : 0)) == 0)
        {
          if (this.Mission.Mode != MissionMode.Barter)
          {
            if (this._missionMainAgentController.LockedAgent != null)
            {
              Vec3 lookDirection = mainAgent1.LookDirection;
              this.CameraBearing = lookDirection.RotationZ;
              lookDirection = mainAgent1.LookDirection;
              this.CameraElevation = lookDirection.RotationX;
            }
            else
            {
              this._cameraSpecialTargetAddedBearing = MBMath.WrapAngle(this._cameraSpecialTargetAddedBearing + this._cameraBearingDelta);
              this._cameraSpecialTargetAddedElevation = MBMath.WrapAngle(this._cameraSpecialTargetAddedElevation + this._cameraElevationDelta);
              this._cameraSpecialCurrentAddedBearing = MBMath.WrapAngle(this._cameraSpecialCurrentAddedBearing + this._cameraBearingDelta);
              this._cameraSpecialCurrentAddedElevation = MBMath.WrapAngle(this._cameraSpecialCurrentAddedElevation + this._cameraElevationDelta);
            }
          }
          this._cameraSpecialTargetAddedElevation = MBMath.ClampFloat(this.CameraElevation + this._cameraSpecialTargetAddedElevation, -1.36590993f, 1.12199748f) - this.CameraElevation;
          this._cameraSpecialCurrentAddedElevation = MBMath.ClampFloat(this.CameraElevation + this._cameraSpecialCurrentAddedElevation, -1.36590993f, 1.12199748f) - this.CameraElevation;
        }
        else
        {
          this._cameraSpecialTargetAddedBearing = 0.0f;
          this._cameraSpecialTargetAddedElevation = 0.0f;
          if (this.Mission.CameraIsFirstPerson && agentToFollow != null && agentToFollow == this.Mission.MainAgent && !this.IsPhotoModeEnabled && !agentToFollow.GetCurrentAnimationFlag(0).HasAnyFlag<AnimFlags>(AnimFlags.anf_lock_camera) && !agentToFollow.GetCurrentAnimationFlag(1).HasAnyFlag<AnimFlags>(AnimFlags.anf_lock_camera) && (this.Mission.Mode != MissionMode.Conversation && this.Mission.Mode != MissionMode.Barter || this._missionMainAgentController?.InteractionComponent.CurrentFocusedObject == null || this._missionMainAgentController.InteractionComponent.CurrentFocusedObject.FocusableObjectType != FocusableObjectType.Agent) && (this._missionMainAgentController == null || !this._missionMainAgentController.CustomLookDir.IsNonZero))
          {
            float cameraBearing = MBMath.WrapAngle(this.CameraBearing + this._cameraBearingDelta);
            float cameraElevation = MBMath.WrapAngle(this.CameraElevation + this._cameraElevationDelta);
            float newBearing;
            float newElevation;
            this.CalculateNewBearingAndElevationForFirstPerson(agentToFollow, cameraBearing, cameraElevation, out newBearing, out newElevation);
            if ((double) newBearing != (double) cameraBearing)
              this._cameraBearingDelta = MBMath.IsBetween(MBMath.WrapAngle(this._cameraBearingDelta), 0.0f, 3.14159274f) ? MBMath.ClampFloat(MBMath.WrapAngle(newBearing - this.CameraBearing), 0.0f, this._cameraBearingDelta) : MBMath.ClampFloat(MBMath.WrapAngle(newBearing - this.CameraBearing), this._cameraBearingDelta, 0.0f);
            if ((double) newElevation != (double) cameraElevation)
              this._cameraElevationDelta = MBMath.IsBetween(MBMath.WrapAngle(this._cameraElevationDelta), 0.0f, 3.14159274f) ? MBMath.ClampFloat(MBMath.WrapAngle(newElevation - this.CameraElevation), 0.0f, this._cameraElevationDelta) : MBMath.ClampFloat(MBMath.WrapAngle(newElevation - this.CameraElevation), this._cameraElevationDelta, 0.0f);
          }
          this.CameraBearing += this._cameraBearingDelta;
          this.CameraElevation += this._cameraElevationDelta;
          this.CameraElevation = MBMath.ClampFloat(this.CameraElevation, -1.36590993f, 1.12199748f);
        }
        if (this.LockCameraMovement)
          this._cameraToggleStartTime = float.MaxValue;
        else if (!Input.IsMouseActive)
        {
          float applicationTime = Time.ApplicationTime;
          if (this.SceneLayer.Input.IsGameKeyPressed(27))
          {
            if ((double) this.SceneLayer.Input.GetGameKeyAxis("MovementAxisX") <= 0.10000000149011612 && (double) this.SceneLayer.Input.GetGameKeyAxis("MovementAxisY") <= 0.10000000149011612)
              this._cameraToggleStartTime = applicationTime;
          }
          else if (!this.SceneLayer.Input.IsGameKeyDown(27))
            this._cameraToggleStartTime = float.MaxValue;
          if ((double) this.GetCameraToggleProgress() < 1.0)
            return;
          this._cameraToggleStartTime = float.MaxValue;
          this.Mission.CameraIsFirstPerson = !this.Mission.CameraIsFirstPerson;
          this._cameraApplySpecialMovementsInstantly = true;
        }
        else
        {
          if (!this.SceneLayer.Input.IsGameKeyPressed(27))
            return;
          this.Mission.CameraIsFirstPerson = !this.Mission.CameraIsFirstPerson;
          this._cameraApplySpecialMovementsInstantly = true;
        }
      }
      else
      {
        if (this.IsPhotoModeEnabled && this.Mission.CameraIsFirstPerson)
          this.Mission.CameraIsFirstPerson = false;
        this.CameraBearing += this._cameraBearingDelta;
        this.CameraElevation += this._cameraElevationDelta;
        this.CameraElevation = MBMath.ClampFloat(this.CameraElevation, -1.36590993f, 1.12199748f);
      }
    }

    public float GetCameraToggleProgress()
    {
      return (double) this._cameraToggleStartTime != 3.4028234663852886E+38 && this.SceneLayer.Input.IsGameKeyDown(27) ? (float) (((double) Time.ApplicationTime - (double) this._cameraToggleStartTime) / 0.5) : 0.0f;
    }

    private bool HandleUserInputCheatMode(float dt)
    {
      bool flag = false;
      if (!GameNetwork.IsMultiplayer)
      {
        if (this.InputManager.IsHotKeyPressed("EnterSlowMotion"))
        {
          if (this.Mission.GetRequestedTimeSpeed(1121, out float _))
            this.Mission.RemoveTimeSpeedRequest(1121);
          else
            this.Mission.AddTimeSpeedRequest(new Mission.TimeSpeedRequest(0.1f, 1121));
          flag = true;
        }
        float requestedTime;
        if (this.Mission.GetRequestedTimeSpeed(1121, out requestedTime))
        {
          if (this.InputManager.IsHotKeyDown("MissionScreenHotkeyIncreaseSlowMotionFactor"))
          {
            this.Mission.RemoveTimeSpeedRequest(1121);
            requestedTime = MBMath.ClampFloat(requestedTime + 0.5f * dt, 0.0f, 1f);
            this.Mission.AddTimeSpeedRequest(new Mission.TimeSpeedRequest(requestedTime, 1121));
          }
          if (this.InputManager.IsHotKeyDown("MissionScreenHotkeyDecreaseSlowMotionFactor"))
          {
            this.Mission.RemoveTimeSpeedRequest(1121);
            requestedTime = MBMath.ClampFloat(requestedTime - 0.5f * dt, 0.0f, 1f);
            this.Mission.AddTimeSpeedRequest(new Mission.TimeSpeedRequest(requestedTime, 1121));
          }
        }
        if (this.InputManager.IsHotKeyPressed("Pause"))
        {
          this._missionState.Paused = !this._missionState.Paused;
          flag = true;
        }
        if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyHealYourSelf") && this.Mission.MainAgent != null)
        {
          this.Mission.MainAgent.Health = this.Mission.MainAgent.HealthLimit;
          flag = true;
        }
        if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyHealYourHorse") && this.Mission.MainAgent?.MountAgent != null)
        {
          this.Mission.MainAgent.MountAgent.Health = this.Mission.MainAgent.MountAgent.HealthLimit;
          flag = true;
        }
        if (!this.InputManager.IsShiftDown())
        {
          if (!this.InputManager.IsAltDown())
          {
            if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillEnemyAgent"))
              return Mission.Current.KillCheats(false, true, false, false);
          }
          else if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillAllEnemyAgents"))
            return Mission.Current.KillCheats(true, true, false, false);
        }
        else if (!this.InputManager.IsAltDown())
        {
          if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillEnemyHorse"))
            return Mission.Current.KillCheats(false, true, true, false);
        }
        else if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillAllEnemyHorses"))
          return Mission.Current.KillCheats(true, true, true, false);
        if (!this.InputManager.IsShiftDown())
        {
          if (!this.InputManager.IsAltDown())
          {
            if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillFriendlyAgent"))
              return Mission.Current.KillCheats(false, false, false, false);
          }
          else if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillAllFriendlyAgents"))
            return Mission.Current.KillCheats(true, false, false, false);
        }
        else if (!this.InputManager.IsAltDown())
        {
          if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillFriendlyHorse"))
            return Mission.Current.KillCheats(false, false, true, false);
        }
        else if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillAllFriendlyHorses"))
          return Mission.Current.KillCheats(true, false, true, false);
        if (!this.InputManager.IsShiftDown())
        {
          if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillYourSelf"))
            return Mission.Current.KillCheats(false, false, false, true);
        }
        else if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyKillYourHorse"))
          return Mission.Current.KillCheats(false, false, true, true);
        if ((GameNetwork.IsServerOrRecorder || !GameNetwork.IsMultiplayer) && this.InputManager.IsHotKeyPressed("MissionScreenHotkeyGhostCam"))
          this.IsCheatGhostMode = !this.IsCheatGhostMode;
      }
      if (!GameNetwork.IsSessionActive)
      {
        if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeySwitchAgentToAi"))
        {
          Debug.Print("Cheat: SwitchAgentToAi");
          if (this.Mission.MainAgent != null && this.Mission.MainAgent.IsActive())
          {
            this.Mission.MainAgent.Controller = this.Mission.MainAgent.Controller == Agent.ControllerType.Player ? Agent.ControllerType.AI : Agent.ControllerType.Player;
            flag = true;
          }
        }
        if (this.InputManager.IsHotKeyPressed("MissionScreenHotkeyControlFollowedAgent"))
        {
          Debug.Print("Cheat: ControlFollowedAgent");
          if (this.Mission.MainAgent != null)
          {
            if (this.Mission.MainAgent.Controller == Agent.ControllerType.Player)
            {
              this.Mission.MainAgent.Controller = Agent.ControllerType.AI;
              if (this.LastFollowedAgent != null)
                this.LastFollowedAgent.Controller = Agent.ControllerType.Player;
            }
            else
            {
              foreach (Agent agent in (List<Agent>) this.Mission.Agents)
              {
                if (agent.Controller == Agent.ControllerType.Player)
                  agent.Controller = Agent.ControllerType.AI;
              }
              this.Mission.MainAgent.Controller = Agent.ControllerType.Player;
            }
            flag = true;
          }
          else
          {
            if (this.LastFollowedAgent != null)
              this.LastFollowedAgent.Controller = Agent.ControllerType.Player;
            flag = true;
          }
        }
      }
      return flag;
    }

    public void AddMissionView(MissionView missionView)
    {
      this.Mission.AddMissionBehavior((MissionBehavior) missionView);
      this.RegisterView(missionView);
      missionView.OnMissionScreenInitialize();
      Debug.ReportMemoryBookmark("MissionView Initialized: " + missionView.GetType().Name);
    }

    public void ScreenPointToWorldRay(Vec2 screenPoint, out Vec3 rayBegin, out Vec3 rayEnd)
    {
      rayBegin = Vec3.Invalid;
      rayEnd = Vec3.Invalid;
      Vec2 viewportPoint = this.SceneView.ScreenPointToViewportPoint(screenPoint);
      this.CombatCamera.ViewportPointToWorldRay(ref rayBegin, ref rayEnd, viewportPoint);
      float b = -1f;
      foreach (KeyValuePair<string, ICollection<Vec2>> boundary in this.Mission.Boundaries)
      {
        float boundaryRadius = this.Mission.Boundaries.GetBoundaryRadius(boundary.Key);
        if ((double) b < (double) boundaryRadius)
          b = boundaryRadius;
      }
      if ((double) b < 0.0)
        b = 30f;
      Vec3 vec3 = rayEnd - rayBegin;
      float a = vec3.Normalize();
      rayEnd = rayBegin + vec3 * MathF.Min(a, b);
    }

    public bool GetProjectedMousePositionOnGround(
      out Vec3 groundPosition,
      out Vec3 groundNormal,
      BodyFlags excludeBodyOwnerFlags,
      bool checkOccludedSurface)
    {
      return this.SceneView.ProjectedMousePositionOnGround(out groundPosition, out groundNormal, this.MouseVisible, excludeBodyOwnerFlags, checkOccludedSurface);
    }

    public void CancelQuickPositionOrder()
    {
      if (this.OrderFlag == null)
        return;
      this.OrderFlag.IsVisible = false;
    }

    public bool MissionStartedRendering()
    {
      return (NativeObject) this.SceneView != (NativeObject) null && this.SceneView.ReadyToRender();
    }

    public Vec3 GetOrderFlagPosition()
    {
      return this.OrderFlag != null ? this.OrderFlag.Position : Vec3.Invalid;
    }

    public MatrixFrame GetOrderFlagFrame() => this.OrderFlag.Frame;

    private void ActivateLoadingScreen()
    {
      if (this.SceneLayer == null || !((NativeObject) this.SceneLayer.SceneView != (NativeObject) null))
        return;
      Scene scene = this.SceneLayer.SceneView.GetScene();
      if (!((NativeObject) scene != (NativeObject) null))
        return;
      scene.PreloadForRendering();
    }

    public void SetRadialMenuActiveState(bool isActive) => this.IsRadialMenuActive = isActive;

    public void SetPhotoModeRequiresMouse(bool isRequired)
    {
      this.PhotoModeRequiresMouse = isRequired;
    }

    public void SetPhotoModeEnabled(bool isEnabled)
    {
      if (this.IsPhotoModeEnabled == isEnabled || GameNetwork.IsMultiplayer)
        return;
      this.IsPhotoModeEnabled = isEnabled;
      if (isEnabled)
      {
        MBCommon.PauseGameEngine();
        foreach (MissionView missionView in this._missionViews)
          missionView.OnPhotoModeActivated();
      }
      else
      {
        MBCommon.UnPauseGameEngine();
        foreach (MissionView missionView in this._missionViews)
          missionView.OnPhotoModeDeactivated();
      }
      this.Mission.Scene.SetPhotoModeOn(this.IsPhotoModeEnabled);
    }

    public void SetConversationActive(bool isActive)
    {
      if (this.IsConversationActive == isActive || GameNetwork.IsMultiplayer)
        return;
      this.IsConversationActive = isActive;
      foreach (MissionView missionView in this._missionViews)
      {
        if (isActive)
          missionView.OnConversationBegin();
        else
          missionView.OnConversationEnd();
      }
    }

    public void SetCameraLockState(bool isLocked) => this.LockCameraMovement = isLocked;

    public void RegisterView(MissionView missionView)
    {
      this._missionViews.Add(missionView);
      missionView.MissionScreen = this;
    }

    public void UnregisterView(MissionView missionView)
    {
      this._missionViews.Remove(missionView);
      missionView.MissionScreen = (MissionScreen) null;
    }

    public IAgentVisual GetPlayerAgentVisuals(MissionPeer lobbyPeer)
    {
      return lobbyPeer.GetAgentVisualForPeer(0);
    }

    public void SetAgentToFollow(Agent agent) => this._agentToFollowOverride = agent;

    public Mission.SpectatorData GetSpectatingData(Vec3 currentCameraPosition)
    {
      Agent agentToFollow = (Agent) null;
      IAgentVisual agentVisualToFollow = (IAgentVisual) null;
      SpectatorCameraTypes spectatorCameraTypes1 = SpectatorCameraTypes.Invalid;
      bool flag1 = this.Mission.MainAgent != null && this.Mission.MainAgent.IsCameraAttachable() && this.Mission.Mode != MissionMode.Deployment;
      bool lockedToMainPlayer = flag1 || this.LastFollowedAgent != null && this.LastFollowedAgent.Controller == Agent.ControllerType.Player && this.LastFollowedAgent.IsCameraAttachable();
      MissionPeer component = GameNetwork.MyPeer != null ? GameNetwork.MyPeer.GetComponent<MissionPeer>() : (MissionPeer) null;
      bool flag2 = component != null && component.HasSpawnedAgentVisuals;
      bool flag3 = this._missionLobbyComponent != null && (this._missionLobbyComponent.MissionType == MultiplayerGameType.Siege || this._missionLobbyComponent.MissionType == MultiplayerGameType.TeamDeathmatch) || this.Mission.Mode == MissionMode.Deployment;
      SpectatorCameraTypes spectatorCameraTypes2;
      if ((((this.IsCheatGhostMode ? 0 : (!lockedToMainPlayer ? 1 : 0)) & (flag3 ? 1 : 0)) == 0 || this._agentToFollowOverride == null || !this._agentToFollowOverride.IsCameraAttachable() ? 0 : (!flag2 ? 1 : 0)) != 0)
      {
        agentToFollow = this._agentToFollowOverride;
        spectatorCameraTypes2 = SpectatorCameraTypes.LockToAnyAgent;
      }
      else
      {
        if (this._missionCameraModeLogic != null)
          spectatorCameraTypes1 = this._missionCameraModeLogic.GetMissionCameraLockMode(lockedToMainPlayer);
        if (this.IsCheatGhostMode)
          spectatorCameraTypes2 = SpectatorCameraTypes.Free;
        else if (spectatorCameraTypes1 != SpectatorCameraTypes.Invalid)
          spectatorCameraTypes2 = spectatorCameraTypes1;
        else if (this.Mission.Mode == MissionMode.Deployment)
          spectatorCameraTypes2 = SpectatorCameraTypes.Free;
        else if (flag1)
        {
          spectatorCameraTypes2 = SpectatorCameraTypes.LockToMainPlayer;
          agentToFollow = this.Mission.MainAgent;
        }
        else if (lockedToMainPlayer)
        {
          spectatorCameraTypes2 = SpectatorCameraTypes.LockToMainPlayer;
          agentToFollow = this.LastFollowedAgent;
        }
        else if (component != null && this.GetPlayerAgentVisuals(component) != null && spectatorCameraTypes1 != SpectatorCameraTypes.Free)
        {
          spectatorCameraTypes2 = SpectatorCameraTypes.LockToPosition;
          agentVisualToFollow = this.GetPlayerAgentVisuals(component);
        }
        else
          spectatorCameraTypes2 = GameNetwork.IsMultiplayer ? (SpectatorCameraTypes) MultiplayerOptions.OptionType.SpectatorCamera.GetIntValue() : SpectatorCameraTypes.Free;
        if ((spectatorCameraTypes2 == SpectatorCameraTypes.LockToMainPlayer ? 1 : (spectatorCameraTypes2 == SpectatorCameraTypes.LockToPosition ? 1 : 0)) == 0 && this.Mission.Mode != MissionMode.Deployment || this.IsCheatGhostMode && !this.IsOrderMenuOpen && !this.IsTransferMenuOpen)
        {
          if (this.LastFollowedAgent != null && this.LastFollowedAgent.IsCameraAttachable())
            agentToFollow = this.LastFollowedAgent;
          else if (spectatorCameraTypes2 != SpectatorCameraTypes.Free || this._gatherCustomAgentListToSpectate != null && this.LastFollowedAgent != null)
            agentToFollow = this.FindNextCameraAttachableAgent(this.LastFollowedAgent, spectatorCameraTypes2, 1, currentCameraPosition);
          bool flag4 = Game.Current.CheatMode && this.InputManager.IsControlDown();
          if (this.InputManager.IsGameKeyReleased(10) || this.InputManager.IsGameKeyReleased(11))
          {
            if (!flag4)
              agentToFollow = this.FindNextCameraAttachableAgent(this.LastFollowedAgent, spectatorCameraTypes2, -1, currentCameraPosition);
          }
          else if ((this.InputManager.IsGameKeyReleased(9) || this.InputManager.IsGameKeyReleased(12)) && !this._rightButtonDraggingMode)
          {
            if (!flag4)
              agentToFollow = this.FindNextCameraAttachableAgent(this.LastFollowedAgent, spectatorCameraTypes2, 1, currentCameraPosition);
          }
          else if ((this.InputManager.IsGameKeyDown(0) || this.InputManager.IsGameKeyDown(1) || this.InputManager.IsGameKeyDown(2) || this.InputManager.IsGameKeyDown(3) || this.InputManager.GetIsControllerConnected() && ((double) Input.GetKeyState(InputKey.ControllerLStick).y != 0.0 || (double) Input.GetKeyState(InputKey.ControllerLStick).x != 0.0)) && spectatorCameraTypes2 == SpectatorCameraTypes.Free)
          {
            agentToFollow = (Agent) null;
            agentVisualToFollow = (IAgentVisual) null;
          }
        }
      }
      return new Mission.SpectatorData(agentToFollow, agentVisualToFollow, spectatorCameraTypes2);
    }

    private Agent FindNextCameraAttachableAgent(
      Agent currentAgent,
      SpectatorCameraTypes cameraLockMode,
      int iterationDirection,
      Vec3 currentCameraPosition)
    {
      if (this.Mission.AllAgents == null || this.Mission.AllAgents.Count == 0)
        return (Agent) null;
      if (MBDebug.IsErrorReportModeActive())
        return (Agent) null;
      MissionPeer missionPeer = GameNetwork.IsMyPeerReady ? GameNetwork.MyPeer.GetComponent<MissionPeer>() : (MissionPeer) null;
      List<Agent> agentList;
      if (this._gatherCustomAgentListToSpectate != null)
      {
        agentList = this._gatherCustomAgentListToSpectate(currentAgent);
      }
      else
      {
        switch (cameraLockMode)
        {
          case SpectatorCameraTypes.LockToAnyAgent:
            agentList = this.Mission.AllAgents.Where<Agent>((Func<Agent, bool>) (x => x.IsCameraAttachable() || x == currentAgent)).ToList<Agent>();
            break;
          case SpectatorCameraTypes.LockToAnyPlayer:
            agentList = this.Mission.AllAgents.Where<Agent>((Func<Agent, bool>) (x => x.MissionPeer != null && x.IsCameraAttachable() || x == currentAgent)).ToList<Agent>();
            break;
          case SpectatorCameraTypes.LockToPlayerFormation:
            agentList = this.Mission.AllAgents.Where<Agent>((Func<Agent, bool>) (x => x.Formation != null && x.Formation == missionPeer?.ControlledFormation && x.IsCameraAttachable() || x == currentAgent)).ToList<Agent>();
            break;
          case SpectatorCameraTypes.LockToTeamMembers:
          case SpectatorCameraTypes.LockToTeamMembersView:
            agentList = this.Mission.AllAgents.Where<Agent>((Func<Agent, bool>) (x => x.Team == this.Mission.PlayerTeam && x.MissionPeer != null && x.IsCameraAttachable() || x == currentAgent)).ToList<Agent>();
            break;
          default:
            agentList = this.Mission.AllAgents.Where<Agent>((Func<Agent, bool>) (x => x.IsCameraAttachable() || x == currentAgent)).ToList<Agent>();
            break;
        }
      }
      Agent cameraAttachableAgent;
      if (agentList.Count - (currentAgent == null || currentAgent.IsCameraAttachable() ? 0 : 1) == 0)
        cameraAttachableAgent = (Agent) null;
      else if (currentAgent == null)
      {
        Agent agent1 = (Agent) null;
        float num = float.MaxValue;
        foreach (Agent agent2 in agentList)
        {
          float lengthSquared = (currentCameraPosition - agent2.Position).LengthSquared;
          if ((double) num > (double) lengthSquared)
          {
            num = lengthSquared;
            agent1 = agent2;
          }
        }
        cameraAttachableAgent = agent1;
      }
      else
      {
        int num = agentList.IndexOf(currentAgent);
        cameraAttachableAgent = iterationDirection != 1 ? (num < 0 ? agentList[agentList.Count - 1] : agentList[(num + agentList.Count - 1) % agentList.Count]) : agentList[(num + 1) % agentList.Count];
      }
      return cameraAttachableAgent;
    }

    void IGameStateListener.OnInitialize()
    {
    }

    void IGameStateListener.OnFinalize()
    {
    }

    void IGameStateListener.OnActivate()
    {
      if (this._isDeactivated)
        this.ActivateMissionView();
      this._isDeactivated = false;
    }

    void IGameStateListener.OnDeactivate()
    {
      this._isDeactivated = true;
      if (this.Mission?.MissionBehaviors != null)
      {
        foreach (MissionView missionView in this._missionViews)
          missionView.OnMissionScreenDeactivate();
      }
      this.OnDeactivate();
    }

    void IMissionSystemHandler.OnMissionAfterStarting(Mission mission)
    {
      this.Mission = mission;
      this.Mission.AddListener((IMissionListener) this);
      foreach (MissionBehavior missionBehavior in this.Mission.MissionBehaviors)
      {
        if (missionBehavior is MissionView missionView)
          this.RegisterView(missionView);
      }
    }

    void IMissionSystemHandler.OnMissionLoadingFinished(Mission mission)
    {
      this.Mission = mission;
      this.InitializeMissionView();
      this.ActivateMissionView();
    }

    void IMissionSystemHandler.BeforeMissionTick(Mission mission, float realDt)
    {
      if (MBEditor.EditModeEnabled)
      {
        if (this.DebugInput.IsHotKeyReleased("EnterEditMode") && mission == null)
        {
          if (MBEditor.IsEditModeOn)
          {
            MBEditor.LeaveEditMode();
            this._tickEditor = false;
          }
          else
          {
            MBEditor.EnterEditMode(this.SceneView, this.CombatCamera.Frame, this.CameraElevation, this.CameraBearing);
            this._tickEditor = true;
          }
        }
        if (this._tickEditor && MBEditor.IsEditModeOn)
        {
          MBEditor.TickEditMode(realDt);
          return;
        }
      }
      if (mission == null || (NativeObject) mission.Scene == (NativeObject) null)
        return;
      mission.Scene.SetOwnerThread();
      mission.Scene.SetDynamicShadowmapCascadesRadiusMultiplier(1f);
      if (MBEditor.EditModeEnabled)
        MBCommon.CheckResourceModifications();
      this.HandleUserInput(realDt);
      if (!this._isRenderingStarted && this.MissionStartedRendering())
      {
        Mission.Current.OnRenderingStarted();
        this._isRenderingStarted = true;
      }
      if (!this._isRenderingStarted || this._loadingScreenFramesLeft < 0 || this._onSceneRenderingStartedCalled)
        return;
      if (this._loadingScreenFramesLeft > 0)
      {
        --this._loadingScreenFramesLeft;
        Mission current = Mission.Current;
        Utilities.SetLoadingScreenPercentage((current != null ? (current.HasMissionBehavior<DeploymentMissionController>() ? 1 : 0) : 0) != 0 ? (this._loadingScreenFramesLeft == 0 ? 1f : (float) (0.92000001668930054 - (double) this._loadingScreenFramesLeft * 0.004999999888241291)) : (float) (1.0 - (double) this._loadingScreenFramesLeft * 0.019999999552965164));
      }
      if (!(this._loadingScreenFramesLeft <= 0 & this.AreViewsReady()) || MBAnimation.IsAnyAnimationLoadingFromDisk())
        return;
      this.OnSceneRenderingStarted();
      this._onSceneRenderingStartedCalled = true;
    }

    private bool AreViewsReady()
    {
      bool flag1 = true;
      foreach (MissionView missionView in this._missionViews)
      {
        bool flag2 = missionView.IsReady();
        flag1 &= flag2;
      }
      return flag1;
    }

    private void CameraTick(Mission mission, float realDt)
    {
      if (mission.CurrentState != Mission.State.Continuing)
        return;
      this.CheckForUpdateCamera(realDt);
    }

    void IMissionSystemHandler.UpdateCamera(Mission mission, float realDt)
    {
      this.CameraTick(mission, realDt);
      if (mission.CurrentState != Mission.State.Continuing || mission.MissionEnded)
        return;
      MBWindowManager.PreDisplay();
    }

    void IMissionSystemHandler.AfterMissionTick(Mission mission, float realDt)
    {
      if ((mission.CurrentState == Mission.State.Continuing || mission.MissionEnded && mission.CurrentState != Mission.State.Over) && Game.Current.CheatMode && this.IsCheatGhostMode && Agent.Main != null && this.InputManager.IsHotKeyPressed("MissionScreenHotkeyTeleportMainAgent"))
      {
        MatrixFrame renderCameraFrame = this.Mission.Scene.LastFinalRenderCameraFrame;
        float collisionDistance;
        if (this.Mission.Scene.RayCastForClosestEntityOrTerrain(renderCameraFrame.origin, renderCameraFrame.origin + -renderCameraFrame.rotation.u * 100f, out collisionDistance, excludeBodyFlags: BodyFlags.CommonCollisionExcludeFlags))
        {
          Vec3 vec3 = renderCameraFrame.origin + -renderCameraFrame.rotation.u * collisionDistance;
          Vec2 vec2 = -renderCameraFrame.rotation.u.AsVec2;
          double num = (double) vec2.Normalize();
          MatrixFrame matrixFrame = new MatrixFrame();
          matrixFrame.origin = vec3;
          matrixFrame.rotation.f = new Vec3(vec2.x, vec2.y);
          matrixFrame.rotation.u = new Vec3(z: 1f);
          matrixFrame.rotation.Orthonormalize();
          Agent.Main.TeleportToPosition(matrixFrame.origin);
        }
      }
      if (this.SceneLayer.Input.IsGameKeyPressed(4) && !this.DebugInput.IsAltDown() && MBEditor.EditModeEnabled && MBEditor.IsEditModeOn)
        MBEditor.LeaveEditMissionMode();
      if (!((NativeObject) mission.Scene == (NativeObject) null))
        return;
      MBDebug.Print("Mission is null on MissionScreen::OnFrameTick second phase");
    }

    IEnumerable<MissionBehavior> IMissionSystemHandler.OnAddBehaviors(
      IEnumerable<MissionBehavior> behaviors,
      Mission mission,
      string missionName,
      bool addDefaultMissionBehaviors)
    {
      if (addDefaultMissionBehaviors)
        behaviors = this.AddDefaultMissionBehaviorsTo(mission, behaviors);
      behaviors = ViewCreatorManager.CollectMissionBehaviors(missionName, mission, behaviors);
      return behaviors;
    }

    private void HandleInputs()
    {
      if (MBEditor.IsEditorMissionOn() || !this.MissionStartedRendering() || !this.SceneLayer.Input.IsHotKeyReleased("ToggleEscapeMenu") || LoadingWindow.IsLoadingWindowActive)
        return;
      this.OnEscape();
    }

    public void OnEscape()
    {
      if (!this.IsMissionTickable)
        return;
      foreach (MissionBehavior missionBehavior in this.Mission.MissionBehaviors.Where<MissionBehavior>((Func<MissionBehavior, bool>) (v => v is MissionView)).OrderBy<MissionBehavior, int>((Func<MissionBehavior, int>) (v => ((MissionView) v).ViewOrderPriority)).ToList<MissionBehavior>())
      {
        MissionView missionView = missionBehavior as MissionView;
        if (!this.IsMissionTickable || missionView.OnEscape())
          break;
      }
    }

    bool IMissionSystemHandler.RenderIsReady() => this.MissionStartedRendering();

    void IMissionListener.OnEndMission()
    {
      this._agentToFollowOverride = (Agent) null;
      this.LastFollowedAgent = (Agent) null;
      this.LastFollowedAgentVisuals = (IAgentVisual) null;
      foreach (MissionView missionView in this._missionViews.ToArray())
      {
        missionView.OnMissionScreenFinalize();
        this.UnregisterView(missionView);
      }
      CraftedDataViewManager.Clear();
      this.Mission.RemoveListener((IMissionListener) this);
    }

    void IMissionListener.OnEquipItemsFromSpawnEquipmentBegin(
      Agent agent,
      Agent.CreationType creationType)
    {
      agent.ClearEquipment();
      agent.AgentVisuals.ClearVisualComponents(false);
    }

    void IMissionListener.OnEquipItemsFromSpawnEquipment(
      Agent agent,
      Agent.CreationType creationType)
    {
      EquipmentElement equipmentElement;
      switch (creationType)
      {
        case Agent.CreationType.FromRoster:
        case Agent.CreationType.FromCharacterObj:
          bool useTeamColor = false;
          Random randomGenerator = (Random) null;
          bool randomizeColors = agent.RandomizeColors;
          uint num1;
          uint num2;
          if (randomizeColors)
          {
            int bodyPropertiesSeed = agent.BodyPropertiesSeed;
            randomGenerator = new Random(bodyPropertiesSeed);
            Color color1;
            Color color2;
            AgentVisuals.GetRandomClothingColors(bodyPropertiesSeed, Color.FromUint(agent.ClothingColor1), Color.FromUint(agent.ClothingColor2), out color1, out color2);
            num1 = color1.ToUnsignedInteger();
            num2 = color2.ToUnsignedInteger();
          }
          else
          {
            num1 = agent.ClothingColor1;
            num2 = agent.ClothingColor2;
          }
          for (EquipmentIndex equipmentIndex = EquipmentIndex.NumAllWeaponSlots; equipmentIndex < EquipmentIndex.ArmorItemEndSlot; ++equipmentIndex)
          {
            equipmentElement = agent.SpawnEquipment[equipmentIndex];
            if (!equipmentElement.IsVisualEmpty)
            {
              ItemObject cosmeticItem = agent.SpawnEquipment[equipmentIndex].CosmeticItem;
              if (cosmeticItem == null)
              {
                equipmentElement = agent.SpawnEquipment[equipmentIndex];
                cosmeticItem = equipmentElement.Item;
              }
              ItemObject itemObject = cosmeticItem;
              int num3;
              if (equipmentIndex == EquipmentIndex.Body)
              {
                equipmentElement = agent.SpawnEquipment[EquipmentIndex.Gloves];
                num3 = equipmentElement.Item != null ? 1 : 0;
              }
              else
                num3 = 0;
              bool hasGloves = num3 != 0;
              bool isFemale = (double) agent.Age >= 14.0 && agent.IsFemale;
              MetaMesh multiMesh = agent.SpawnEquipment[equipmentIndex].GetMultiMesh(isFemale, hasGloves, true);
              if ((NativeObject) multiMesh != (NativeObject) null)
              {
                if (randomizeColors)
                  multiMesh.SetGlossMultiplier(AgentVisuals.GetRandomGlossFactor(randomGenerator));
                if (itemObject.IsUsingTableau && agent?.Origin?.Banner != null)
                {
                  for (int meshIndex = 0; meshIndex < multiMesh.MeshCount; ++meshIndex)
                  {
                    Mesh currentMesh = multiMesh.GetMeshAtIndex(meshIndex);
                    Mesh mesh1 = currentMesh;
                    if ((mesh1 != null ? (!mesh1.HasTag("dont_use_tableau") ? 1 : 0) : 0) != 0)
                    {
                      Mesh mesh2 = currentMesh;
                      if ((mesh2 != null ? (mesh2.HasTag("banner_replacement_mesh") ? 1 : 0) : 0) != 0)
                      {
                        ((BannerVisual) agent.Origin.Banner.BannerVisual).GetTableauTextureLarge((Action<Texture>) (t => MissionScreen.ApplyBannerTextureToMesh(currentMesh, t)));
                        currentMesh.ManualInvalidate();
                        break;
                      }
                    }
                    currentMesh.ManualInvalidate();
                  }
                }
                else if (itemObject.IsUsingTeamColor)
                {
                  for (int meshIndex = 0; meshIndex < multiMesh.MeshCount; ++meshIndex)
                  {
                    Mesh meshAtIndex = multiMesh.GetMeshAtIndex(meshIndex);
                    if (!meshAtIndex.HasTag("no_team_color"))
                    {
                      meshAtIndex.Color = num1;
                      meshAtIndex.Color2 = num2;
                      Material copy = meshAtIndex.GetMaterial().CreateCopy();
                      copy.AddMaterialShaderFlag("use_double_colormap_with_mask_texture", false);
                      meshAtIndex.SetMaterial(copy);
                      useTeamColor = true;
                    }
                    meshAtIndex.ManualInvalidate();
                  }
                }
                if (itemObject.UsingFacegenScaling)
                  multiMesh.UseHeadBoneFaceGenScaling(agent.AgentVisuals.GetSkeleton(), agent.Monster.HeadLookDirectionBoneIndex, agent.AgentVisuals.GetFacegenScalingMatrix());
                Skeleton skeleton = agent.AgentVisuals.GetSkeleton();
                int num4 = skeleton != null ? skeleton.GetComponentCount(GameEntity.ComponentType.ClothSimulator) : -1;
                agent.AgentVisuals.AddMultiMesh(multiMesh, MBAgentVisuals.GetBodyMeshIndex(equipmentIndex));
                multiMesh.ManualInvalidate();
                int num5 = skeleton != null ? skeleton.GetComponentCount(GameEntity.ComponentType.ClothSimulator) : -1;
                if ((NativeObject) skeleton != (NativeObject) null && equipmentIndex == EquipmentIndex.Cape && num5 > num4)
                {
                  GameEntityComponent componentAtIndex = skeleton.GetComponentAtIndex(GameEntity.ComponentType.ClothSimulator, num5 - 1);
                  agent.SetCapeClothSimulator(componentAtIndex);
                }
              }
              if (equipmentIndex == EquipmentIndex.Body && !string.IsNullOrEmpty(itemObject.ArmBandMeshName))
              {
                MetaMesh copy1 = MetaMesh.GetCopy(itemObject.ArmBandMeshName, mayReturnNull: true);
                if ((NativeObject) copy1 != (NativeObject) null)
                {
                  if (randomizeColors)
                    copy1.SetGlossMultiplier(AgentVisuals.GetRandomGlossFactor(randomGenerator));
                  if (itemObject.IsUsingTeamColor)
                  {
                    for (int meshIndex = 0; meshIndex < copy1.MeshCount; ++meshIndex)
                    {
                      Mesh meshAtIndex = copy1.GetMeshAtIndex(meshIndex);
                      if (!meshAtIndex.HasTag("no_team_color"))
                      {
                        meshAtIndex.Color = num1;
                        meshAtIndex.Color2 = num2;
                        Material copy2 = meshAtIndex.GetMaterial().CreateCopy();
                        copy2.AddMaterialShaderFlag("use_double_colormap_with_mask_texture", false);
                        meshAtIndex.SetMaterial(copy2);
                        useTeamColor = true;
                      }
                      meshAtIndex.ManualInvalidate();
                    }
                  }
                  agent.AgentVisuals.AddMultiMesh(copy1, MBAgentVisuals.GetBodyMeshIndex(equipmentIndex));
                  copy1.ManualInvalidate();
                }
              }
            }
          }
          equipmentElement = agent.SpawnEquipment[EquipmentIndex.Body];
          ItemObject itemObject1 = equipmentElement.Item;
          if (itemObject1 != null)
          {
            int lodAtlasIndex = itemObject1.LodAtlasIndex;
            if (lodAtlasIndex != -1)
            {
              agent.AgentVisuals.SetLodAtlasShadingIndex(lodAtlasIndex, useTeamColor, agent.ClothingColor1, agent.ClothingColor2);
              break;
            }
            break;
          }
          break;
        case Agent.CreationType.FromHorseObj:
          MBAgentVisuals agentVisuals = agent.AgentVisuals;
          ItemObject mountItem = agent.SpawnEquipment[EquipmentIndex.ArmorItemEndSlot].Item;
          equipmentElement = agent.SpawnEquipment[EquipmentIndex.HorseHarness];
          ItemObject harnessItem = equipmentElement.Item;
          string horseCreationKey = agent.HorseCreationKey;
          Agent agent1 = agent;
          MountVisualCreator.AddMountMeshToAgentVisual(agentVisuals, mountItem, harnessItem, horseCreationKey, agent1);
          break;
      }
      ArmorComponent.ArmorMaterialTypes bodyArmorMaterialType = ArmorComponent.ArmorMaterialTypes.None;
      equipmentElement = agent.SpawnEquipment[EquipmentIndex.Body];
      ItemObject itemObject2 = equipmentElement.Item;
      if (itemObject2 != null)
        bodyArmorMaterialType = itemObject2.ArmorComponent.MaterialType;
      agent.SetBodyArmorMaterialType(bodyArmorMaterialType);
    }

    void IMissionListener.OnConversationCharacterChanged() => this._cameraAddSpecialMovement = true;

    void IMissionListener.OnMissionModeChange(MissionMode oldMissionMode, bool atStart)
    {
      if (this.Mission.Mode == MissionMode.Conversation && oldMissionMode != MissionMode.Conversation)
      {
        this._cameraAddSpecialMovement = true;
        this._cameraApplySpecialMovementsInstantly = atStart;
      }
      else if (this.Mission.Mode == MissionMode.Battle && oldMissionMode == MissionMode.Deployment && (NativeObject) this.CombatCamera != (NativeObject) null)
      {
        this._cameraAddSpecialMovement = true;
        this._cameraApplySpecialMovementsInstantly = atStart || this._playerDeploymentCancelled;
        Agent agentToFollow = this.GetSpectatingData(this.CombatCamera.Position).AgentToFollow;
        if (!atStart)
          this.LastFollowedAgent = agentToFollow;
        this._cameraSpecialCurrentAddedElevation = this.CameraElevation;
        if (agentToFollow != null)
        {
          this._cameraSpecialCurrentAddedBearing = MBMath.WrapAngle(this.CameraBearing - agentToFollow.LookDirectionAsAngle);
          this._cameraSpecialCurrentPositionToAdd = this.CombatCamera.Position - agentToFollow.VisualPosition;
          this.CameraBearing = agentToFollow.LookDirectionAsAngle;
        }
        else
        {
          this._cameraSpecialCurrentAddedBearing = 0.0f;
          this._cameraSpecialCurrentPositionToAdd = Vec3.Zero;
          this.CameraBearing = 0.0f;
        }
        this.CameraElevation = 0.0f;
      }
      if ((this.Mission.Mode == MissionMode.Conversation || this.Mission.Mode == MissionMode.Barter) && oldMissionMode != MissionMode.Conversation && oldMissionMode != MissionMode.Barter || (oldMissionMode == MissionMode.Conversation || oldMissionMode == MissionMode.Barter) && this.Mission.Mode != MissionMode.Conversation && this.Mission.Mode != MissionMode.Barter)
      {
        this._cameraAddSpecialMovement = true;
        this._cameraAddSpecialPositionalMovement = true;
        this._cameraApplySpecialMovementsInstantly = atStart;
      }
      this._cameraHeightLimit = 0.0f;
      if (this.Mission.Mode == MissionMode.Deployment)
      {
        GameEntity gameEntity = this.Mission.PlayerTeam.Side != BattleSideEnum.Attacker ? this.Mission.Scene.FindEntityWithTag("strategyCameraDefender") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker") : this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraDefender");
        if (!((NativeObject) gameEntity != (NativeObject) null))
          return;
        this._cameraHeightLimit = gameEntity.GetGlobalFrame().origin.z;
      }
      else
      {
        GameEntity entityWithTag = this.Mission.Scene.FindEntityWithTag("camera_height_limiter");
        if (!((NativeObject) entityWithTag != (NativeObject) null))
          return;
        this._cameraHeightLimit = entityWithTag.GetGlobalFrame().origin.z;
      }
    }

    void IMissionListener.OnResetMission()
    {
      this._agentToFollowOverride = (Agent) null;
      this.LastFollowedAgent = (Agent) null;
      this.LastFollowedAgentVisuals = (IAgentVisual) null;
    }

    void IMissionListener.OnInitialDeploymentPlanMade(BattleSideEnum battleSide, bool isFirstPlan)
    {
      if (((GameNetwork.IsMultiplayer ? 0 : (this.Mission.Mode == MissionMode.Deployment ? 1 : 0)) & (isFirstPlan ? 1 : 0)) != 0)
      {
        BattleSideEnum side = this.Mission.PlayerTeam.Side;
        if (side == battleSide)
        {
          DeploymentMissionController missionBehavior = this.Mission.GetMissionBehavior<DeploymentMissionController>();
          bool flag1 = missionBehavior != null && MissionGameModels.Current.BattleInitializationModel.CanPlayerSideDeployWithOrderOfBattle();
          if ((side != BattleSideEnum.Attacker ? (NativeObject) (this.Mission.Scene.FindEntityWithTag("strategyCameraDefender") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker")) : (NativeObject) (this.Mission.Scene.FindEntityWithTag("strategyCameraAttacker") ?? this.Mission.Scene.FindEntityWithTag("strategyCameraDefender"))) == (NativeObject) null & flag1)
          {
            MatrixFrame sideDeploymentFrame = this.Mission.DeploymentPlan.GetBattleSideDeploymentFrame(side);
            MatrixFrame matrixFrame = sideDeploymentFrame;
            float num = Math.Max(0.2f * (float) this.Mission.DeploymentPlan.GetTroopCountForSide(side, DeploymentPlanType.Initial), 32f);
            matrixFrame.rotation.RotateAboutSide(-0.5235988f);
            matrixFrame.origin -= num * matrixFrame.rotation.f;
            bool flag2 = false;
            if (this.Mission.IsPositionInsideBoundaries(matrixFrame.origin.AsVec2))
            {
              flag2 = true;
            }
            else
            {
              IEnumerable<KeyValuePair<string, ICollection<Vec2>>> source1 = this.Mission.Boundaries.Where<KeyValuePair<string, ICollection<Vec2>>>((Func<KeyValuePair<string, ICollection<Vec2>>, bool>) (boundary => boundary.Key == "walk_area"));
              if (!source1.IsEmpty<KeyValuePair<string, ICollection<Vec2>>>())
              {
                List<Vec2> source2 = source1.First<KeyValuePair<string, ICollection<Vec2>>>().Value as List<Vec2>;
                List<Vec2> boundaries = source2 ?? source2.ToList<Vec2>();
                Vec2 rayDir = matrixFrame.rotation.f.AsVec2.Normalized();
                Vec2 asVec2_1 = matrixFrame.origin.AsVec2;
                Vec2 intersectionPoint;
                if (MBMath.IntersectRayWithBoundaryList(asVec2_1, rayDir, boundaries, out intersectionPoint))
                {
                  Vec2 asVec2_2 = sideDeploymentFrame.origin.AsVec2;
                  float z = intersectionPoint.Distance(asVec2_2) / Math.Max(asVec2_1.Distance(asVec2_2), 0.1f) * matrixFrame.origin.z;
                  Vec3 vec3 = new Vec3(intersectionPoint, z);
                  matrixFrame.origin = vec3;
                  flag2 = true;
                }
              }
            }
            if (!flag2)
            {
              matrixFrame = sideDeploymentFrame;
              matrixFrame.origin.z += 20f;
            }
            this.CombatCamera.Frame = matrixFrame;
            this.CameraBearing = matrixFrame.rotation.f.RotationZ;
            this.CameraElevation = matrixFrame.rotation.f.RotationX;
          }
          this._playerDeploymentCancelled = missionBehavior != null && !flag1;
        }
      }
      foreach (MissionView missionView in this._missionViews)
        missionView.OnInitialDeploymentPlanMadeForSide(battleSide, isFirstPlan);
    }

    private void CalculateNewBearingAndElevationForFirstPerson(
      Agent agentToFollow,
      float cameraBearing,
      float cameraElevation,
      out float newBearing,
      out float newElevation)
    {
      newBearing = cameraBearing;
      newElevation = cameraElevation;
      long currentAnimationFlag1 = (long) agentToFollow.GetCurrentAnimationFlag(0);
      AnimFlags currentAnimationFlag2 = agentToFollow.GetCurrentAnimationFlag(1);
      if (!((AnimFlags) currentAnimationFlag1).HasAnyFlag<AnimFlags>(AnimFlags.anf_lock_movement | AnimFlags.anf_synch_with_ladder_movement) && !currentAnimationFlag2.HasAnyFlag<AnimFlags>(AnimFlags.anf_lock_movement | AnimFlags.anf_synch_with_ladder_movement) && agentToFollow.MovementLockedState != AgentMovementLockedState.FrameLocked)
        return;
      MatrixFrame boneEntitialFrame = agentToFollow.AgentVisuals.GetBoneEntitialFrame(agentToFollow.Monster.ThoraxLookDirectionBoneIndex, true);
      MatrixFrame frame = agentToFollow.AgentVisuals.GetFrame();
      float rotationZ = boneEntitialFrame.rotation.f.RotationZ;
      float restrictionCenter = rotationZ + frame.rotation.f.RotationZ;
      float radians1 = 66f.ToRadians();
      if ((double) Math.Abs(rotationZ) > (double) radians1 * 0.5 - 9.9999997473787516E-05)
      {
        float num = Math.Abs(rotationZ) - (float) ((double) radians1 * 0.5 - 9.9999997473787516E-05);
        radians1 += num;
        restrictionCenter += num * ((double) rotationZ < 0.0 ? 0.5f : -0.5f);
      }
      if ((double) Math.Abs(rotationZ) > (double) radians1 * 0.5 - 9.9999997473787516E-05)
      {
        float num = Math.Abs(rotationZ) - (float) ((double) radians1 * 0.5 - 9.9999997473787516E-05);
        radians1 += num;
        restrictionCenter += num * ((double) rotationZ < 0.0 ? 0.5f : -0.5f);
      }
      if ((double) restrictionCenter <= -3.1415927410125732)
        restrictionCenter += 6.28318548f;
      else if ((double) restrictionCenter > 3.1415927410125732)
        restrictionCenter -= 6.28318548f;
      newBearing = MBMath.ClampAngle(MBMath.WrapAngle(cameraBearing), restrictionCenter, radians1);
      float radians2 = 50f.ToRadians();
      newElevation = MBMath.ClampAngle(MBMath.WrapAngle(cameraElevation), frame.rotation.f.RotationX, radians2);
    }

    private static void ApplyBannerTextureToMesh(Mesh armorMesh, Texture bannerTexture)
    {
      if (!((NativeObject) armorMesh != (NativeObject) null))
        return;
      Material copy = armorMesh.GetMaterial().CreateCopy();
      copy.SetTexture(Material.MBTextureType.DiffuseMap2, bannerTexture);
      uint materialShaderFlagMask = (uint) copy.GetShader().GetMaterialShaderFlagMask("use_tableau_blending");
      ulong shaderFlags = copy.GetShaderFlags();
      copy.SetShaderFlags(shaderFlags | (ulong) materialShaderFlagMask);
      armorMesh.SetMaterial(copy);
    }

    public delegate void OnSpectateAgentDelegate(Agent followedAgent);

    public delegate List<Agent> GatherCustomAgentListToSpectateDelegate(Agent forcedAgentToInclude);
  }
}
